/Doc/library/imputil.rst
http://unladen-swallow.googlecode.com/ · ReStructuredText · 238 lines · 175 code · 63 blank · 0 comment · 0 complexity · 5eb476dc8a28cdab6f51a0557a3df63d MD5 · raw file
- :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.0.
- .. 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 builtin 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.