183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh""" 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehImport utilities 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehExported classes: 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ImportManager Manage the import process 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Importer Base class for replacing standard import functions 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh BuiltinImporter Emulate the import mechanism for builtin and frozen modules 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh DynLoadSuffixImporter 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh""" 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom warnings import warnpy3k 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehwarnpy3k("the imputil module has been removed in Python 3.0", stacklevel=2) 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdel warnpy3k 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# note: avoid importing non-builtin modules 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport imp ### not available in Jython? 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport __builtin__ 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# for the DirectoryImporter 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport struct 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport marshal 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh__all__ = ["ImportManager","Importer","BuiltinImporter"] 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_StringType = type('') 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_ModuleType = type(sys) ### doesn't work in Jython... 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass ImportManager: 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Manage the import process." 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def install(self, namespace=vars(__builtin__)): 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Install this ImportManager into the specified namespace." 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if isinstance(namespace, _ModuleType): 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh namespace = vars(namespace) 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Note: we have no notion of "chaining" 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Record the previous import hook, then install our own. 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.previous_importer = namespace['__import__'] 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.namespace = namespace 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh namespace['__import__'] = self._import_hook 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ### fix this 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh #namespace['reload'] = self._reload_hook 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def uninstall(self): 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Restore the previous import mechanism." 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.namespace['__import__'] = self.previous_importer 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def add_suffix(self, suffix, importFunc): 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert hasattr(importFunc, '__call__') 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.fs_imp.add_suffix(suffix, importFunc) 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ###################################################################### 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # PRIVATE METHODS 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh clsFilesystemImporter = None 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, fs_imp=None): 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # we're definitely going to be importing something in the future, 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # so let's just load the OS-related facilities. 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not _os_stat: 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh _os_bootstrap() 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # This is the Importer that we use for grabbing stuff from the 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # filesystem. It defines one more method (import_from_dir) for our use. 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if fs_imp is None: 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh cls = self.clsFilesystemImporter or _FilesystemImporter 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fs_imp = cls() 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.fs_imp = fs_imp 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Initialize the set of suffixes that we recognize and import. 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # The default will import dynamic-load modules first, followed by 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # .py files (or a .py file's cached bytecode) 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for desc in imp.get_suffixes(): 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if desc[2] == imp.C_EXTENSION: 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.add_suffix(desc[0], 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh DynLoadSuffixImporter(desc).import_file) 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.add_suffix('.py', py_suffix_importer) 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _import_hook(self, fqname, globals=None, locals=None, fromlist=None): 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Python calls this hook to locate and import a module.""" 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parts = fqname.split('.') 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # determine the context of this import 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent = self._determine_import_context(globals) 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if there is a parent, then its importer should manage this import 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if parent: 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = parent.__importer__._do_import(parent, parts, fromlist) 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if module: 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return module 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # has the top module already been imported? 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh top_module = sys.modules[parts[0]] 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except KeyError: 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # look for the topmost module 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh top_module = self._import_top_module(parts[0]) 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not top_module: 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the topmost module wasn't found at all. 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError, 'No module named ' + fqname 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # fast-path simple imports 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if len(parts) == 1: 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not fromlist: 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return top_module 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not top_module.__dict__.get('__ispkg__'): 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # __ispkg__ isn't defined (the module was not imported by us), 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # or it is zero. 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # In the former case, there is no way that we could import 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # sub-modules that occur in the fromlist (but we can't raise an 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # error because it may just be names) because we don't know how 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # to deal with packages that were imported by other systems. 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # In the latter case (__ispkg__ == 0), there can't be any sub- 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # modules present, so we can just return. 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # In both cases, since len(parts) == 1, the top_module is also 12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the "bottom" which is the defined return when a fromlist 13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # exists. 13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return top_module 13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh importer = top_module.__dict__.get('__importer__') 13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if importer: 13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return importer._finish_import(top_module, parts[1:], fromlist) 13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Grrr, some people "import os.path" or do "from os.path import ..." 13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if len(parts) == 2 and hasattr(top_module, parts[1]): 13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if fromlist: 14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return getattr(top_module, parts[1]) 14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return top_module 14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # If the importer does not exist, then we have to bail. A missing 14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # importer means that something else imported the module, and we have 14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # no knowledge of how to get sub-modules out of the thing. 14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError, 'No module named ' + fqname 14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _determine_import_context(self, globals): 15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Returns the context in which a module should be imported. 15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh The context could be a loaded (package) module and the imported module 15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh will be looked for within that package. The context could also be None, 15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh meaning there is no context -- the module should be looked for as a 15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "top-level" module. 15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not globals or not globals.get('__importer__'): 15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # globals does not refer to one of our modules or packages. That 16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # implies there is no relative import context (as far as we are 16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # concerned), and it should just pick it off the standard path. 16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # The globals refer to a module or package of ours. It will define 16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the context of the new import. Get the module/package fqname. 16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent_fqname = globals['__name__'] 16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if a package is performing the import, then return itself (imports 16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # refer to pkg contents) 17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if globals['__ispkg__']: 17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent = sys.modules[parent_fqname] 17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert globals is parent.__dict__ 17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return parent 17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh i = parent_fqname.rfind('.') 17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # a module outside of a package has no particular import context 17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if i == -1: 17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if a module in a package is performing the import, then return the 18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # package (imports refer to siblings) 18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent_fqname = parent_fqname[:i] 18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent = sys.modules[parent_fqname] 18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert parent.__name__ == parent_fqname 18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return parent 18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _import_top_module(self, name): 18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # scan sys.path looking for a location in the filesystem that contains 19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the module, or an Importer object that can import the module. 19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for item in sys.path: 19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if isinstance(item, _StringType): 19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = self.fs_imp.import_from_dir(item, name) 19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = item.import_top(name) 19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if module: 19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return module 19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _reload_hook(self, module): 20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Python calls this hook to reload a module." 20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # reloading of a module may or may not be possible (depending on the 20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # importer), but at least we can validate that it's ours to reload 20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh importer = module.__dict__.get('__importer__') 20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not importer: 20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ### oops. now what... 20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # okay. it is using the imputil system, and we must delegate it, but 21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # we don't know what to do (yet) 21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ### we should blast the module dict and do another get_code(). need to 21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ### flesh this out and add proper docco... 21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise SystemError, "reload not yet implemented" 21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Importer: 21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Base class for replacing standard import functions." 21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def import_top(self, name): 22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Import a top-level module." 22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._import_one(None, name, name) 22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ###################################################################### 22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # PRIVATE METHODS 22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _finish_import(self, top, parts, fromlist): 22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if "a.b.c" was provided, then load the ".b.c" portion down from 23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # below the top-level module. 23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh bottom = self._load_tail(top, parts) 23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if the form is "import a.b.c", then return "a" 23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not fromlist: 23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # no fromlist: return the top of the import tree 23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return top 23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the top module was imported by self. 23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # this means that the bottom module was also imported by self (just 24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # now, or in the past and we fetched it from sys.modules). 24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # since we imported/handled the bottom module, this means that we can 24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # also handle its fromlist (and reliably use __ispkg__). 24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if the bottom node is a package, then (potentially) import some 24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # modules. 24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # note: if it is not a package, then "fromlist" refers to names in 25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the bottom module rather than modules. 25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # note: for a mix of names and modules in the fromlist, we will 25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # import all modules and insert those into the namespace of 25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the package module. Python will pick up all fromlist names 25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # from the bottom (package) module; some will be modules that 25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # we imported and stored in the namespace, others are expected 25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # to be present already. 25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if bottom.__ispkg__: 25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._import_fromlist(bottom, fromlist) 25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if the form is "from a.b import c, d" then return "b" 26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return bottom 26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _import_one(self, parent, modname, fqname): 26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Import a single module." 26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # has the module already been imported? 26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return sys.modules[fqname] 26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except KeyError: 27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # load the module's code, or fetch the module itself 27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh result = self.get_code(parent, modname, fqname) 27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if result is None: 27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = self._process_result(result, fqname) 27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # insert the module into its parent 28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if parent: 28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh setattr(parent, modname, module) 28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return module 28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _process_result(self, result, fqname): 28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ispkg, code, values = result 28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # did get_code() return an actual module? (rather than a code object) 28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh is_module = isinstance(code, _ModuleType) 28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # use the returned module, or create a new one to exec code into 29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if is_module: 29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = code 29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = imp.new_module(fqname) 29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ### record packages a bit differently?? 29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module.__importer__ = self 29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module.__ispkg__ = ispkg 29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # insert additional values into the module (before executing the code) 30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module.__dict__.update(values) 30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the module is almost ready... make it visible 30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.modules[fqname] = module 30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # execute the code within the module's namespace 30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not is_module: 30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exec code in module.__dict__ 30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if fqname in sys.modules: 31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del sys.modules[fqname] 31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise 31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # fetch from sys.modules instead of returning module directly. 31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # also make module's __name__ agree with fqname, in case 31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # the "exec code in module.__dict__" played games on us. 31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = sys.modules[fqname] 31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module.__name__ = fqname 31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return module 32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _load_tail(self, m, parts): 32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Import the rest of the modules, down from the top-level module. 32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Returns the last module in the dotted list of modules. 32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for part in parts: 32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fqname = "%s.%s" % (m.__name__, part) 32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m = self._import_one(m, part, fqname) 32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not m: 33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError, "No module named " + fqname 33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return m 33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _import_fromlist(self, package, fromlist): 33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'Import any sub-modules in the "from" list.' 33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if '*' is present in the fromlist, then look for the '__all__' 33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # variable to find additional items (modules) to import. 33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if '*' in fromlist: 33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fromlist = list(fromlist) + \ 34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh list(package.__dict__.get('__all__', [])) 34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for sub in fromlist: 34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # if the name is already present, then don't try to import it (it 34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # might not be a module!). 34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if sub != '*' and not hasattr(package, sub): 34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh subname = "%s.%s" % (package.__name__, sub) 34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh submod = self._import_one(package, sub, subname) 34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not submod: 34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError, "cannot import name " + subname 35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _do_import(self, parent, parts, fromlist): 35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Attempt to import the module relative to parent. 35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh This method is used when the import context specifies that <self> 35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh imported the parent module. 35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh top_name = parts[0] 35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh top_fqname = parent.__name__ + '.' + top_name 35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh top_module = self._import_one(parent, top_name, top_fqname) 36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not top_module: 36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # this importer and parent could not find the module (relatively) 36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._finish_import(top_module, parts[1:], fromlist) 36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ###################################################################### 36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # METHODS TO OVERRIDE 36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_code(self, parent, modname, fqname): 37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Find and retrieve the code for the given module. 37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh parent specifies a parent module to define a context for importing. It 37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh may be None, indicating no particular context for the search. 37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh modname specifies a single module (not dotted) within the parent. 37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fqname specifies the fully-qualified module name. This is a 37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (potentially) dotted name from the "root" of the module namespace 38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh down to the modname. 38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh If there is no parent, then modname==fqname. 38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh This method should return None, or a 3-tuple. 38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh * If the module was not found, then None should be returned. 38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh * The first item of the 2- or 3-tuple should be the integer 0 or 1, 38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh specifying whether the module that was found is a package or not. 38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh * The second item is the code object for the module (it will be 39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh executed within the new module's namespace). This item can also 39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh be a fully-loaded module object (e.g. loaded from a shared lib). 39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh * The third item is a dictionary of name/value pairs that will be 39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh inserted into new module before the code object is executed. This 39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh is provided in case the module's code expects certain values (such 39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh as where the module was found). When the second item is a module 39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh object, then these names/values will be inserted *after* the module 39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh has been loaded/initialized. 40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise RuntimeError, "get_code not implemented" 40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Some handy stuff for the Importers 40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# byte-compiled file suffix character 41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_suffix_char = __debug__ and 'c' or 'o' 41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# byte-compiled file suffix 41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_suffix = '.py' + _suffix_char 41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _compile(pathname, timestamp): 41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Compile (and cache) a Python source file. 41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh The file specified by <pathname> is compiled to a code object and 41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh returned. 42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Presuming the appropriate privileges exist, the bytecodes will be 42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh saved back to the filesystem for future imports. The source file's 42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh modification timestamp must be provided as a Long value. 42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh codestring = open(pathname, 'rU').read() 42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if codestring and codestring[-1] != '\n': 42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh codestring = codestring + '\n' 42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh code = __builtin__.compile(codestring, pathname, 'exec') 42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # try to cache the compiled code 43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f = open(pathname + _suffix_char, 'wb') 43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except IOError: 43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.write('\0\0\0\0') 43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.write(struct.pack('<I', timestamp)) 43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh marshal.dump(code, f) 43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.flush() 44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.seek(0, 0) 44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.write(imp.get_magic()) 44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.close() 44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return code 44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_os_stat = _os_path_join = None 44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _os_bootstrap(): 44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Set up 'os' module replacement functions for use during import bootstrap." 44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh names = sys.builtin_module_names 45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh join = None 45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if 'posix' in names: 45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sep = '/' 45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from posix import stat 45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif 'nt' in names: 45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sep = '\\' 45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from nt import stat 45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif 'dos' in names: 46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sep = '\\' 46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from dos import stat 46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif 'os2' in names: 46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sep = '\\' 46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from os2 import stat 46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError, 'no os specific module found' 46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if join is None: 46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def join(a, b, sep=sep): 47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if a == '': 47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return b 47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh lastchar = a[-1:] 47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if lastchar == '/' or lastchar == sep: 47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return a + b 47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return a + sep + b 47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global _os_stat 47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh _os_stat = stat 47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global _os_path_join 48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh _os_path_join = join 48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _os_path_isdir(pathname): 48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Local replacement for os.path.isdir()." 48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = _os_stat(pathname) 48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except OSError: 48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return (s.st_mode & 0170000) == 0040000 49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _timestamp(pathname): 49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Return the file modification time as a Long." 49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = _os_stat(pathname) 49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except OSError: 49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return long(s.st_mtime) 49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Emulate the import mechanism for builtin and frozen modules 50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BuiltinImporter(Importer): 50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_code(self, parent, modname, fqname): 50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if parent: 50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # these modules definitely do not occur within a package context 50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # look for the module 51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if imp.is_builtin(modname): 51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh type = imp.C_BUILTIN 51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif imp.is_frozen(modname): 51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh type = imp.PY_FROZEN 51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # not found 51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # got it. now load and return it. 52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = imp.load_module(modname, None, modname, ('', '', type)) 52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 0, module, { } 52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Internal importer used for importing from the filesystem 52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass _FilesystemImporter(Importer): 52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): 53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.suffixes = [ ] 53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def add_suffix(self, suffix, importFunc): 53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert hasattr(importFunc, '__call__') 53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.suffixes.append((suffix, importFunc)) 53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def import_from_dir(self, dir, fqname): 53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh result = self._import_pathname(_os_path_join(dir, fqname), fqname) 53883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if result: 53983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._process_result(result, fqname) 54083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 54183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 54283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_code(self, parent, modname, fqname): 54383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # This importer is never used with an empty parent. Its existence is 54483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # private to the ImportManager. The ImportManager uses the 54583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # import_from_dir() method to import top-level modules/packages. 54683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # This method is only used when we look for a module within a package. 54783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert parent 54883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 54983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for submodule_path in parent.__path__: 55083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh code = self._import_pathname(_os_path_join(submodule_path, modname), fqname) 55183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if code is not None: 55283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return code 55383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), 55483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fqname) 55583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 55683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _import_pathname(self, pathname, fqname): 55783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if _os_path_isdir(pathname): 55883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh result = self._import_pathname(_os_path_join(pathname, '__init__'), 55983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fqname) 56083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if result: 56183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh values = result[2] 56283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh values['__pkgdir__'] = pathname 56383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh values['__path__'] = [ pathname ] 56483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1, result[1], values 56583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 56683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 56783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for suffix, importFunc in self.suffixes: 56883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh filename = pathname + suffix 56983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 57083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finfo = _os_stat(filename) 57183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except OSError: 57283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 57383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 57483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return importFunc(filename, finfo, fqname) 57583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 57683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 57783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 57883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 57983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# SUFFIX-BASED IMPORTERS 58083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 58183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 58283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef py_suffix_importer(filename, finfo, fqname): 58383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh file = filename[:-3] + _suffix 58483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh t_py = long(finfo[8]) 58583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh t_pyc = _timestamp(file) 58683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 58783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh code = None 58883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if t_pyc is not None and t_pyc >= t_py: 58983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f = open(file, 'rb') 59083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if f.read(4) == imp.get_magic(): 59183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh t = struct.unpack('<I', f.read(4))[0] 59283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if t == t_py: 59383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh code = marshal.load(f) 59483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f.close() 59583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if code is None: 59683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh file = filename 59783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh code = _compile(file, t_py) 59883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 59983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 0, code, { '__file__' : file } 60083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 60183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass DynLoadSuffixImporter: 60283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, desc): 60383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.desc = desc 60483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 60583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def import_file(self, filename, finfo, fqname): 60683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fp = open(filename, self.desc[1]) 60783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module = imp.load_module(fqname, fp, filename, self.desc) 60883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh module.__file__ = filename 60983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 0, module, { } 61083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 61183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 61283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 61383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 61483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _print_importers(): 61583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh items = sys.modules.items() 61683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh items.sort() 61783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for name, module in items: 61883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if module: 61983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print name, module.__dict__.get('__importer__', '-- no importer') 62083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 62183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print name, '-- non-existent module' 62283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 62383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _test_revamp(): 62483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ImportManager().install() 62583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.path.insert(0, BuiltinImporter()) 62683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 62783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh###################################################################### 62883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 62983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 63083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# TODO 63183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 63283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# from Finn Bock: 63383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# type(sys) is not a module in Jython. what to use instead? 63483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# imp.C_EXTENSION is not in Jython. same for get_suffixes and new_module 63583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 63683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# given foo.py of: 63783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# import sys 63883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# sys.modules['foo'] = sys 63983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 64083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ---- standard import mechanism 64183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> import foo 64283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> foo 64383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# <module 'sys' (built-in)> 64483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 64583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ---- revamped import mechanism 64683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> import imputil 64783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> imputil._test_revamp() 64883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> import foo 64983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# >>> foo 65083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# <module 'foo' from 'foo.py'> 65183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 65283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 65383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# from MAL: 65483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# should BuiltinImporter exist in sys.path or hard-wired in ImportManager? 65583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# need __path__ processing 65683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# performance 65783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# move chaining to a subclass [gjs: it's been nuked] 65883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# deinstall should be possible 65983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# query mechanism needed: is a specific Importer installed? 66083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# py/pyc/pyo piping hooks to filter/process these files 66183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# wish list: 66283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# distutils importer hooked to list of standard Internet repositories 66383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# module->file location mapper to speed FS-based imports 66483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# relative imports 66583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# keep chaining so that it can play nice with other import hooks 66683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 66783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# from Gordon: 66883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# push MAL's mapper into sys.path[0] as a cache (hard-coded for apps) 66983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 67083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# from Guido: 67183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# need to change sys.* references for rexec environs 67283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy 67383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# watch out for sys.modules[...] is None 67483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# flag to force absolute imports? (speeds _determine_import_context and 67583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# checking for a relative module) 67683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# insert names of archives into sys.path (see quote below) 67783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# note: reload does NOT blast module dict 67883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# shift import mechanisms and policies around; provide for hooks, overrides 67983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# (see quote below) 68083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# add get_source stuff 68183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# get_topcode and get_subcode 68283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# CRLF handling in _compile 68383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# race condition in _compile 68483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# refactoring of os.py to deal with _os_bootstrap problem 68583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# any special handling to do for importing a module with a SyntaxError? 68683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# (e.g. clean up the traceback) 68783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# implement "domain" for path-type functionality using pkg namespace 68883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# (rather than FS-names like __path__) 68983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# don't use the word "private"... maybe "internal" 69083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 69183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 69283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Guido's comments on sys.path caching: 69383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 69483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# We could cache this in a dictionary: the ImportManager can have a 69583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# cache dict mapping pathnames to importer objects, and a separate 69683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# method for coming up with an importer given a pathname that's not yet 69783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# in the cache. The method should do a stat and/or look at the 69883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# extension to decide which importer class to use; you can register new 69983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# importer classes by registering a suffix or a Boolean function, plus a 70083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# class. If you register a new importer class, the cache is zapped. 70183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# The cache is independent from sys.path (but maintained per 70283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ImportManager instance) so that rearrangements of sys.path do the 70383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# right thing. If a path is dropped from sys.path the corresponding 70483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# cache entry is simply no longer used. 70583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 70683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# My/Guido's comments on factoring ImportManager and Importer: 70783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 70883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > However, we still have a tension occurring here: 70983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > 71083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > 1) implementing policy in ImportManager assists in single-point policy 71183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > changes for app/rexec situations 71283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > 2) implementing policy in Importer assists in package-private policy 71383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > changes for normal, operating conditions 71483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > 71583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > I'll see if I can sort out a way to do this. Maybe the Importer class will 71683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > implement the methods (which can be overridden to change policy) by 71783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# > delegating to ImportManager. 71883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 71983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Maybe also think about what kind of policies an Importer would be 72083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# likely to want to change. I have a feeling that a lot of the code 72183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# there is actually not so much policy but a *necessity* to get things 72283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# working given the calling conventions for the __import__ hook: whether 72383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# to return the head or tail of a dotted name, or when to do the "finish 72483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# fromlist" stuff. 72583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 726