14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""Utilities to support packages.""" 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# NOTE: This module must remain compatible with Python 2.3, as it is shared 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# by setuptools for distribution with Python 2.3 and up. 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport imp 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os.path 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom types import ModuleType 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__all__ = [ 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'get_importer', 'iter_importers', 'get_loader', 'find_loader', 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'walk_packages', 'iter_modules', 'get_data', 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao] 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef read_code(stream): 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This helper is needed in order for the PEP 302 emulation to 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # correctly handle compiled files 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import marshal 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao magic = stream.read(4) 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if magic != imp.get_magic(): 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stream.read(4) # Skip timestamp 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return marshal.load(stream) 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef simplegeneric(func): 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Make a trivial single-dispatch generic function""" 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao registry = {} 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def wrapper(*args, **kw): 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ob = args[0] 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = ob.__class__ 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except AttributeError: 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = type(ob) 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mro = cls.__mro__ 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except AttributeError: 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class cls(cls, object): 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mro = cls.__mro__[1:] 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except TypeError: 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mro = object, # must be an ExtensionClass or some such :( 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for t in mro: 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if t in registry: 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return registry[t](*args, **kw) 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return func(*args, **kw) 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao wrapper.__name__ = func.__name__ 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except (TypeError, AttributeError): 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass # Python 2.3 doesn't allow functions to be renamed 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def register(typ, func=None): 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if func is None: 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return lambda f: register(typ, f) 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao registry[typ] = func 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return func 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao wrapper.__dict__ = func.__dict__ 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao wrapper.__doc__ = func.__doc__ 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao wrapper.register = register 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return wrapper 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef walk_packages(path=None, prefix='', onerror=None): 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Yields (module_loader, name, ispkg) for all modules recursively 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao on path, or, if path is None, all accessible modules. 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'path' should be either None or a list of paths to look for 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modules in. 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'prefix' is a string to output on the front of every module name 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao on output. 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Note that this function must import all *packages* (NOT all 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modules!) on the given path, in order to access the __path__ 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao attribute to find submodules. 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'onerror' is a function which gets called with one argument (the 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao name of the package which was being imported) if any exception 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao occurs while trying to import a package. If no onerror function is 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao supplied, ImportErrors are caught and ignored, while all other 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exceptions are propagated, terminating the search. 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Examples: 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # list all modules python can access 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao walk_packages() 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # list all submodules of ctypes 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao walk_packages(ctypes.__path__, ctypes.__name__+'.') 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def seen(p, m={}): 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if p in m: 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return True 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao m[p] = True 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for importer, name, ispkg in iter_modules(path, prefix): 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield importer, name, ispkg 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if ispkg: 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao __import__(name) 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ImportError: 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if onerror is not None: 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao onerror(name) 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except Exception: 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if onerror is not None: 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao onerror(name) 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = getattr(sys.modules[name], '__path__', None) or [] 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # don't traverse path items we've seen before 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = [p for p in path if not seen(p)] 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for item in walk_packages(path, name+'.', onerror): 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield item 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef iter_modules(path=None, prefix=''): 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Yields (module_loader, name, ispkg) for all submodules on path, 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao or, if path is None, all top-level modules on sys.path. 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'path' should be either None or a list of paths to look for 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modules in. 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'prefix' is a string to output on the front of every module name 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao on output. 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if path is None: 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importers = iter_importers() 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importers = map(get_importer, path) 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded = {} 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in importers: 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, ispkg in iter_importer_modules(i, prefix): 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if name not in yielded: 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded[name] = 1 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield i, name, ispkg 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#@simplegeneric 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef iter_importer_modules(importer, prefix=''): 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not hasattr(importer, 'iter_modules'): 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return [] 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return importer.iter_modules(prefix) 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoiter_importer_modules = simplegeneric(iter_importer_modules) 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass ImpImporter: 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """PEP 302 Importer that wraps Python's "classic" import algorithm 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ImpImporter(dirname) produces a PEP 302 importer that searches that 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao directory. ImpImporter(None) produces a PEP 302 importer that searches 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao the current sys.path, plus any modules that are frozen or built-in. 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Note that ImpImporter does not currently support being used by placement 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao on sys.meta_path. 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, path=None): 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.path = path 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def find_module(self, fullname, path=None): 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Note: we ignore 'path' argument since it is only used via meta_path 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao subname = fullname.split(".")[-1] 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if subname != fullname and self.path is None: 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.path is None: 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = None 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = [os.path.realpath(self.path)] 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao file, filename, etc = imp.find_module(subname, path) 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ImportError: 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return ImpLoader(fullname, file, filename, etc) 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def iter_modules(self, prefix=''): 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.path is None or not os.path.isdir(self.path): 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded = {} 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import inspect 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao filenames = os.listdir(self.path) 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except OSError: 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ignore unreadable directories like import does 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao filenames = [] 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao filenames.sort() # handle packages before same-named modules 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fn in filenames: 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modname = inspect.getmodulename(fn) 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if modname=='__init__' or modname in yielded: 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = os.path.join(self.path, fn) 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ispkg = False 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not modname and os.path.isdir(path) and '.' not in fn: 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modname = fn 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dircontents = os.listdir(path) 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except OSError: 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ignore unreadable directories like import does 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dircontents = [] 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fn in dircontents: 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao subname = inspect.getmodulename(fn) 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if subname=='__init__': 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ispkg = True 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue # not a package 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if modname and '.' not in modname: 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded[modname] = 1 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield prefix + modname, ispkg 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass ImpLoader: 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """PEP 302 Loader that wraps Python's "classic" import algorithm 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao code = source = None 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, fullname, file, filename, etc): 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file = file 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.filename = filename 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.fullname = fullname 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.etc = etc 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def load_module(self, fullname): 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._reopen() 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod = imp.load_module(fullname, self.file, self.filename, self.etc) 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.file: 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file.close() 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Note: we don't set __loader__ because we want the module to look 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # normal; i.e. this is just a wrapper for standard import machinery 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return mod 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_data(self, pathname): 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return open(pathname, "rb").read() 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _reopen(self): 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.file and self.file.closed: 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod_type = self.etc[2] 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if mod_type==imp.PY_SOURCE: 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file = open(self.filename, 'rU') 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION): 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file = open(self.filename, 'rb') 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _fix_name(self, fullname): 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if fullname is None: 2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = self.fullname 2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif fullname != self.fullname: 2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise ImportError("Loader for module %s cannot handle " 2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "module %s" % (self.fullname, fullname)) 2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return fullname 2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def is_package(self, fullname): 2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = self._fix_name(fullname) 2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.etc[2]==imp.PKG_DIRECTORY 2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_code(self, fullname=None): 2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = self._fix_name(fullname) 2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.code is None: 2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod_type = self.etc[2] 2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if mod_type==imp.PY_SOURCE: 2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao source = self.get_source(fullname) 2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.code = compile(source, self.filename, 'exec') 2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif mod_type==imp.PY_COMPILED: 2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._reopen() 2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.code = read_code(self.file) 2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file.close() 2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif mod_type==imp.PKG_DIRECTORY: 2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.code = self._get_delegate().get_code() 2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.code 2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_source(self, fullname=None): 2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = self._fix_name(fullname) 2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.source is None: 2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod_type = self.etc[2] 2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if mod_type==imp.PY_SOURCE: 2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._reopen() 3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.source = self.file.read() 3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.file.close() 3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif mod_type==imp.PY_COMPILED: 3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if os.path.exists(self.filename[:-1]): 3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = open(self.filename[:-1], 'rU') 3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.source = f.read() 3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif mod_type==imp.PKG_DIRECTORY: 3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.source = self._get_delegate().get_source() 3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.source 3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _get_delegate(self): 3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return ImpImporter(self.filename).find_module('__init__') 3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_filename(self, fullname=None): 3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = self._fix_name(fullname) 3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod_type = self.etc[2] 3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.etc[2]==imp.PKG_DIRECTORY: 3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._get_delegate().get_filename() 3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION): 3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.filename 3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry: 3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import zipimport 3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from zipimport import zipimporter 3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def iter_zipimport_modules(importer, prefix=''): 3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dirlist = zipimport._zip_directory_cache[importer.archive].keys() 3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dirlist.sort() 3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _prefix = importer.prefix 3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao plen = len(_prefix) 3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded = {} 3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import inspect 3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fn in dirlist: 3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not fn.startswith(_prefix): 3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fn = fn[plen:].split(os.sep) 3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if len(fn)==2 and fn[1].startswith('__init__.py'): 3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if fn[0] not in yielded: 3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded[fn[0]] = 1 3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield fn[0], True 3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if len(fn)!=1: 3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modname = inspect.getmodulename(fn[0]) 3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if modname=='__init__': 3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if modname and '.' not in modname and modname not in yielded: 3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yielded[modname] = 1 3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield prefix + modname, False 3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao iter_importer_modules.register(zipimporter, iter_zipimport_modules) 3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept ImportError: 3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef get_importer(path_item): 3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Retrieve a PEP 302 importer for the given path item 3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The returned importer is cached in sys.path_importer_cache 3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if it was newly created by a path hook. 3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If there is no importer, a wrapper around the basic import 3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao machinery is returned. This wrapper is never inserted into 3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao the importer cache (None is inserted instead). 3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The cache (or part of it) can be cleared manually if a 3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao rescan of sys.path_hooks is necessary. 3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importer = sys.path_importer_cache[path_item] 3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except KeyError: 3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for path_hook in sys.path_hooks: 3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importer = path_hook(path_item) 3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ImportError: 3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importer = None 3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.path_importer_cache.setdefault(path_item, importer) 3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if importer is None: 3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importer = ImpImporter(path_item) 3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ImportError: 3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao importer = None 3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return importer 3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef iter_importers(fullname=""): 4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Yield PEP 302 importers for the given module name 4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If fullname contains a '.', the importers will be for the package 4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao containing fullname, otherwise they will be importers for sys.meta_path, 4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.path, and Python's "classic" import machinery, in that order. If 4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao the named module is in a package, that package is imported as a side 4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao effect of invoking this function. 4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Non PEP 302 mechanisms (e.g. the Windows registry) used by the 4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao standard import machinery to find files in alternative locations 4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao are partially supported, but are searched AFTER sys.path. Normally, 4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao these locations are searched BEFORE sys.path, preventing sys.path 4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao entries from shadowing them. 4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao For this to cause a visible difference in behaviour, there must 4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao be a module or package name that is accessible via both sys.path 4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao and one of the non PEP 302 file system mechanisms. In this case, 4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao the emulation will find the former version, while the builtin 4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import mechanism will find the latter. 4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Items of the following types can be affected by this discrepancy: 4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY 4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if fullname.startswith('.'): 4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise ImportError("Relative module names not supported") 4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if '.' in fullname: 4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Get the containing package's __path__ 4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pkg = '.'.join(fullname.split('.')[:-1]) 4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if pkg not in sys.modules: 4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao __import__(pkg) 4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = getattr(sys.modules[pkg], '__path__', None) or [] 4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for importer in sys.meta_path: 4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield importer 4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = sys.path 4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for item in path: 4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield get_importer(item) 4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if '.' not in fullname: 4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield ImpImporter() 4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef get_loader(module_or_name): 4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Get a PEP 302 "loader" object for module_or_name 4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If the module or package is accessible via the normal import 4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mechanism, a wrapper around the relevant part of that machinery 4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao is returned. Returns None if the module cannot be found or imported. 4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If the named module is not already imported, its containing package 4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (if any) is imported, in order to establish the package __path__. 4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao This function uses iter_importers(), and is thus subject to the same 4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao limitations regarding platform-specific special import locations such 4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao as the Windows registry. 4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if module_or_name in sys.modules: 4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao module_or_name = sys.modules[module_or_name] 4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(module_or_name, ModuleType): 4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao module = module_or_name 4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao loader = getattr(module, '__loader__', None) 4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if loader is not None: 4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return loader 4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = module.__name__ 4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fullname = module_or_name 4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return find_loader(fullname) 4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef find_loader(fullname): 4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Find a PEP 302 "loader" object for fullname 4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If fullname contains dots, path must be the containing package's __path__. 4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Returns None if the module cannot be found or imported. This function uses 4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao iter_importers(), and is thus subject to the same limitations regarding 4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao platform-specific special import locations such as the Windows registry. 4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for importer in iter_importers(fullname): 4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao loader = importer.find_module(fullname) 4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if loader is not None: 4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return loader 4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 4804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef extend_path(path, name): 4834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Extend a package's path. 4844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Intended use is to place the following code in a package's __init__.py: 4864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from pkgutil import extend_path 4884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao __path__ = extend_path(__path__, __name__) 4894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao This will add to the package's __path__ all subdirectories of 4914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao directories on sys.path named after the package. This is useful 4924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if one wants to distribute different parts of a single logical 4934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao package as multiple directories. 4944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao It also looks for *.pkg files beginning where * matches the name 4964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao argument. This feature is similar to *.pth files (see site.py), 4974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except that it doesn't special-case lines starting with 'import'. 4984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao A *.pkg file is trusted at face value: apart from checking for 4994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao duplicates, all entries found in a *.pkg file are added to the 5004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path, regardless of whether they are exist the filesystem. (This 5014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao is a feature.) 5024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If the input path is not a list (as is the case for frozen 5044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao packages) it is returned unchanged. The input path is not 5054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao modified; an extended copy is returned. Items are only appended 5064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao to the copy at the end. 5074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao It is assumed that sys.path is a sequence. Items of sys.path that 5094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao are not (unicode or 8-bit) strings referring to existing 5104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao directories are ignored. Unicode items of sys.path that cause 5114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao errors when used as filenames may cause this function to raise an 5124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exception (in line with os.path.isdir() behavior). 5134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 5144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not isinstance(path, list): 5164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This could happen e.g. when this is called from inside a 5174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # frozen package. Return the path unchanged in that case. 5184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return path 5194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pname = os.path.join(*name.split('.')) # Reconstitute as relative path 5214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Just in case os.extsep != '.' 5224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sname = os.extsep.join(name.split('.')) 5234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sname_pkg = sname + os.extsep + "pkg" 5244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao init_py = "__init__" + os.extsep + "py" 5254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path = path[:] # Start with a copy of the existing path 5274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dir in sys.path: 5294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not isinstance(dir, basestring) or not os.path.isdir(dir): 5304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 5314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao subdir = os.path.join(dir, pname) 5324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX This may still add duplicate entries to path on 5334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # case-insensitive filesystems 5344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao initfile = os.path.join(subdir, init_py) 5354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if subdir not in path and os.path.isfile(initfile): 5364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path.append(subdir) 5374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # XXX Is this the right thing for subpackages like zope.app? 5384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It looks for a file named "zope.app.pkg" 5394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pkgfile = os.path.join(dir, sname_pkg) 5404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if os.path.isfile(pkgfile): 5414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 5424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = open(pkgfile) 5434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except IOError, msg: 5444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stderr.write("Can't open %s: %s\n" % 5454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (pkgfile, msg)) 5464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 5474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for line in f: 5484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao line = line.rstrip('\n') 5494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not line or line.startswith('#'): 5504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao continue 5514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao path.append(line) # Don't check for existence! 5524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 5534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return path 5554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef get_data(package, resource): 5574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Get a resource from a package. 5584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao This is a wrapper round the PEP 302 loader get_data API. The package 5604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao argument should be the name of a package, in standard module format 5614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (foo.bar). The resource argument should be in the form of a relative 5624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao filename, using '/' as the path separator. The parent directory name '..' 5634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao is not allowed, and nor is a rooted name (starting with a '/'). 5644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The function returns a binary string, which is the contents of the 5664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao specified resource. 5674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao For packages located in the filesystem, which have already been imported, 5694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao this is the rough equivalent of 5704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = os.path.dirname(sys.modules[package].__file__) 5724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao data = open(os.path.join(d, resource), 'rb').read() 5734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao If the package cannot be located or loaded, or it uses a PEP 302 loader 5754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao which does not support get_data(), then None is returned. 5764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 5774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao loader = get_loader(package) 5794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if loader is None or not hasattr(loader, 'get_data'): 5804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 5814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao mod = sys.modules.get(package) or loader.load_module(package) 5824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if mod is None or not hasattr(mod, '__file__'): 5834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 5844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Modify the resource name to be compatible with the loader.get_data 5864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # signature - an os.path format "filename" starting with the dirname of 5874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the package's __file__ 5884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao parts = resource.split('/') 5894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao parts.insert(0, os.path.dirname(mod.__file__)) 5904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao resource_name = os.path.join(*parts) 5914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return loader.get_data(resource_name) 592