| :mod:`imputil` --- Import utilities | |
| ===================================================== | |
| .. module:: imputil | |
| :synopsis: Manage and augment the import process. | |
| :deprecated: | |
| .. deprecated:: 2.6 | |
| The :mod:`imputil` module has been removed in Python 3. | |
| .. index:: statement: import | |
| This module provides a very handy and useful mechanism for custom | |
| :keyword:`import` hooks. Compared to the older :mod:`ihooks` module, | |
| :mod:`imputil` takes a dramatically simpler and more straight-forward | |
| approach to custom :keyword:`import` functions. | |
| .. class:: ImportManager([fs_imp]) | |
| Manage the import process. | |
| .. method:: ImportManager.install([namespace]) | |
| Install this ImportManager into the specified namespace. | |
| .. method:: ImportManager.uninstall() | |
| Restore the previous import mechanism. | |
| .. method:: ImportManager.add_suffix(suffix, importFunc) | |
| Undocumented. | |
| .. class:: Importer() | |
| Base class for replacing standard import functions. | |
| .. method:: Importer.import_top(name) | |
| Import a top-level module. | |
| .. method:: Importer.get_code(parent, modname, fqname) | |
| Find and retrieve the code for the given module. | |
| *parent* specifies a parent module to define a context for importing. | |
| It may be ``None``, indicating no particular context for the search. | |
| *modname* specifies a single module (not dotted) within the parent. | |
| *fqname* specifies the fully-qualified module name. This is a | |
| (potentially) dotted name from the "root" of the module namespace | |
| down to the modname. | |
| If there is no parent, then modname==fqname. | |
| This method should return ``None``, or a 3-tuple. | |
| * If the module was not found, then ``None`` should be returned. | |
| * The first item of the 2- or 3-tuple should be the integer 0 or 1, | |
| specifying whether the module that was found is a package or not. | |
| * The second item is the code object for the module (it will be | |
| executed within the new module's namespace). This item can also | |
| be a fully-loaded module object (e.g. loaded from a shared lib). | |
| * The third item is a dictionary of name/value pairs that will be | |
| inserted into new module before the code object is executed. This | |
| is provided in case the module's code expects certain values (such | |
| as where the module was found). When the second item is a module | |
| object, then these names/values will be inserted *after* the module | |
| has been loaded/initialized. | |
| .. class:: BuiltinImporter() | |
| Emulate the import mechanism for built-in and frozen modules. This is a | |
| sub-class of the :class:`Importer` class. | |
| .. method:: BuiltinImporter.get_code(parent, modname, fqname) | |
| Undocumented. | |
| .. function:: py_suffix_importer(filename, finfo, fqname) | |
| Undocumented. | |
| .. class:: DynLoadSuffixImporter([desc]) | |
| Undocumented. | |
| .. method:: DynLoadSuffixImporter.import_file(filename, finfo, fqname) | |
| Undocumented. | |
| .. _examples-imputil: | |
| Examples | |
| -------- | |
| This is a re-implementation of hierarchical module import. | |
| This code is intended to be read, not executed. However, it does work | |
| -- all you need to do to enable it is "import knee". | |
| (The name is a pun on the clunkier predecessor of this module, "ni".) | |
| :: | |
| import sys, imp, __builtin__ | |
| # Replacement for __import__() | |
| def import_hook(name, globals=None, locals=None, fromlist=None): | |
| parent = determine_parent(globals) | |
| q, tail = find_head_package(parent, name) | |
| m = load_tail(q, tail) | |
| if not fromlist: | |
| return q | |
| if hasattr(m, "__path__"): | |
| ensure_fromlist(m, fromlist) | |
| return m | |
| def determine_parent(globals): | |
| if not globals or not globals.has_key("__name__"): | |
| return None | |
| pname = globals['__name__'] | |
| if globals.has_key("__path__"): | |
| parent = sys.modules[pname] | |
| assert globals is parent.__dict__ | |
| return parent | |
| if '.' in pname: | |
| i = pname.rfind('.') | |
| pname = pname[:i] | |
| parent = sys.modules[pname] | |
| assert parent.__name__ == pname | |
| return parent | |
| return None | |
| def find_head_package(parent, name): | |
| if '.' in name: | |
| i = name.find('.') | |
| head = name[:i] | |
| tail = name[i+1:] | |
| else: | |
| head = name | |
| tail = "" | |
| if parent: | |
| qname = "%s.%s" % (parent.__name__, head) | |
| else: | |
| qname = head | |
| q = import_module(head, qname, parent) | |
| if q: return q, tail | |
| if parent: | |
| qname = head | |
| parent = None | |
| q = import_module(head, qname, parent) | |
| if q: return q, tail | |
| raise ImportError("No module named " + qname) | |
| def load_tail(q, tail): | |
| m = q | |
| while tail: | |
| i = tail.find('.') | |
| if i < 0: i = len(tail) | |
| head, tail = tail[:i], tail[i+1:] | |
| mname = "%s.%s" % (m.__name__, head) | |
| m = import_module(head, mname, m) | |
| if not m: | |
| raise ImportError("No module named " + mname) | |
| return m | |
| def ensure_fromlist(m, fromlist, recursive=0): | |
| for sub in fromlist: | |
| if sub == "*": | |
| if not recursive: | |
| try: | |
| all = m.__all__ | |
| except AttributeError: | |
| pass | |
| else: | |
| ensure_fromlist(m, all, 1) | |
| continue | |
| if sub != "*" and not hasattr(m, sub): | |
| subname = "%s.%s" % (m.__name__, sub) | |
| submod = import_module(sub, subname, m) | |
| if not submod: | |
| raise ImportError("No module named " + subname) | |
| def import_module(partname, fqname, parent): | |
| try: | |
| return sys.modules[fqname] | |
| except KeyError: | |
| pass | |
| try: | |
| fp, pathname, stuff = imp.find_module(partname, | |
| parent and parent.__path__) | |
| except ImportError: | |
| return None | |
| try: | |
| m = imp.load_module(fqname, fp, pathname, stuff) | |
| finally: | |
| if fp: fp.close() | |
| if parent: | |
| setattr(parent, partname, m) | |
| return m | |
| # Replacement for reload() | |
| def reload_hook(module): | |
| name = module.__name__ | |
| if '.' not in name: | |
| return import_module(name, name, None) | |
| i = name.rfind('.') | |
| pname = name[:i] | |
| parent = sys.modules[pname] | |
| return import_module(name[i+1:], name, parent) | |
| # Save the original hooks | |
| original_import = __builtin__.__import__ | |
| original_reload = __builtin__.reload | |
| # Now install our hooks | |
| __builtin__.__import__ = import_hook | |
| __builtin__.reload = reload_hook | |
| .. index:: | |
| module: knee | |
| Also see the :mod:`importers` module (which can be found | |
| in :file:`Demo/imputil/` in the Python source distribution) for additional | |
| examples. | |