/Doc/library/imputil.rst

http://unladen-swallow.googlecode.com/ · ReStructuredText · 238 lines · 175 code · 63 blank · 0 comment · 0 complexity · 5eb476dc8a28cdab6f51a0557a3df63d MD5 · raw file

  1. :mod:`imputil` --- Import utilities
  2. =====================================================
  3. .. module:: imputil
  4. :synopsis: Manage and augment the import process.
  5. :deprecated:
  6. .. deprecated:: 2.6
  7. The :mod:`imputil` module has been removed in Python 3.0.
  8. .. index:: statement: import
  9. This module provides a very handy and useful mechanism for custom
  10. :keyword:`import` hooks. Compared to the older :mod:`ihooks` module,
  11. :mod:`imputil` takes a dramatically simpler and more straight-forward
  12. approach to custom :keyword:`import` functions.
  13. .. class:: ImportManager([fs_imp])
  14. Manage the import process.
  15. .. method:: ImportManager.install([namespace])
  16. Install this ImportManager into the specified namespace.
  17. .. method:: ImportManager.uninstall()
  18. Restore the previous import mechanism.
  19. .. method:: ImportManager.add_suffix(suffix, importFunc)
  20. Undocumented.
  21. .. class:: Importer()
  22. Base class for replacing standard import functions.
  23. .. method:: Importer.import_top(name)
  24. Import a top-level module.
  25. .. method:: Importer.get_code(parent, modname, fqname)
  26. Find and retrieve the code for the given module.
  27. *parent* specifies a parent module to define a context for importing.
  28. It may be ``None``, indicating no particular context for the search.
  29. *modname* specifies a single module (not dotted) within the parent.
  30. *fqname* specifies the fully-qualified module name. This is a
  31. (potentially) dotted name from the "root" of the module namespace
  32. down to the modname.
  33. If there is no parent, then modname==fqname.
  34. This method should return ``None``, or a 3-tuple.
  35. * If the module was not found, then ``None`` should be returned.
  36. * The first item of the 2- or 3-tuple should be the integer 0 or 1,
  37. specifying whether the module that was found is a package or not.
  38. * The second item is the code object for the module (it will be
  39. executed within the new module's namespace). This item can also
  40. be a fully-loaded module object (e.g. loaded from a shared lib).
  41. * The third item is a dictionary of name/value pairs that will be
  42. inserted into new module before the code object is executed. This
  43. is provided in case the module's code expects certain values (such
  44. as where the module was found). When the second item is a module
  45. object, then these names/values will be inserted *after* the module
  46. has been loaded/initialized.
  47. .. class:: BuiltinImporter()
  48. Emulate the import mechanism for builtin and frozen modules. This is a
  49. sub-class of the :class:`Importer` class.
  50. .. method:: BuiltinImporter.get_code(parent, modname, fqname)
  51. Undocumented.
  52. .. function:: py_suffix_importer(filename, finfo, fqname)
  53. Undocumented.
  54. .. class:: DynLoadSuffixImporter([desc])
  55. Undocumented.
  56. .. method:: DynLoadSuffixImporter.import_file(filename, finfo, fqname)
  57. Undocumented.
  58. .. _examples-imputil:
  59. Examples
  60. --------
  61. This is a re-implementation of hierarchical module import.
  62. This code is intended to be read, not executed. However, it does work
  63. -- all you need to do to enable it is "import knee".
  64. (The name is a pun on the clunkier predecessor of this module, "ni".)
  65. ::
  66. import sys, imp, __builtin__
  67. # Replacement for __import__()
  68. def import_hook(name, globals=None, locals=None, fromlist=None):
  69. parent = determine_parent(globals)
  70. q, tail = find_head_package(parent, name)
  71. m = load_tail(q, tail)
  72. if not fromlist:
  73. return q
  74. if hasattr(m, "__path__"):
  75. ensure_fromlist(m, fromlist)
  76. return m
  77. def determine_parent(globals):
  78. if not globals or not globals.has_key("__name__"):
  79. return None
  80. pname = globals['__name__']
  81. if globals.has_key("__path__"):
  82. parent = sys.modules[pname]
  83. assert globals is parent.__dict__
  84. return parent
  85. if '.' in pname:
  86. i = pname.rfind('.')
  87. pname = pname[:i]
  88. parent = sys.modules[pname]
  89. assert parent.__name__ == pname
  90. return parent
  91. return None
  92. def find_head_package(parent, name):
  93. if '.' in name:
  94. i = name.find('.')
  95. head = name[:i]
  96. tail = name[i+1:]
  97. else:
  98. head = name
  99. tail = ""
  100. if parent:
  101. qname = "%s.%s" % (parent.__name__, head)
  102. else:
  103. qname = head
  104. q = import_module(head, qname, parent)
  105. if q: return q, tail
  106. if parent:
  107. qname = head
  108. parent = None
  109. q = import_module(head, qname, parent)
  110. if q: return q, tail
  111. raise ImportError, "No module named " + qname
  112. def load_tail(q, tail):
  113. m = q
  114. while tail:
  115. i = tail.find('.')
  116. if i < 0: i = len(tail)
  117. head, tail = tail[:i], tail[i+1:]
  118. mname = "%s.%s" % (m.__name__, head)
  119. m = import_module(head, mname, m)
  120. if not m:
  121. raise ImportError, "No module named " + mname
  122. return m
  123. def ensure_fromlist(m, fromlist, recursive=0):
  124. for sub in fromlist:
  125. if sub == "*":
  126. if not recursive:
  127. try:
  128. all = m.__all__
  129. except AttributeError:
  130. pass
  131. else:
  132. ensure_fromlist(m, all, 1)
  133. continue
  134. if sub != "*" and not hasattr(m, sub):
  135. subname = "%s.%s" % (m.__name__, sub)
  136. submod = import_module(sub, subname, m)
  137. if not submod:
  138. raise ImportError, "No module named " + subname
  139. def import_module(partname, fqname, parent):
  140. try:
  141. return sys.modules[fqname]
  142. except KeyError:
  143. pass
  144. try:
  145. fp, pathname, stuff = imp.find_module(partname,
  146. parent and parent.__path__)
  147. except ImportError:
  148. return None
  149. try:
  150. m = imp.load_module(fqname, fp, pathname, stuff)
  151. finally:
  152. if fp: fp.close()
  153. if parent:
  154. setattr(parent, partname, m)
  155. return m
  156. # Replacement for reload()
  157. def reload_hook(module):
  158. name = module.__name__
  159. if '.' not in name:
  160. return import_module(name, name, None)
  161. i = name.rfind('.')
  162. pname = name[:i]
  163. parent = sys.modules[pname]
  164. return import_module(name[i+1:], name, parent)
  165. # Save the original hooks
  166. original_import = __builtin__.__import__
  167. original_reload = __builtin__.reload
  168. # Now install our hooks
  169. __builtin__.__import__ = import_hook
  170. __builtin__.reload = reload_hook
  171. .. index::
  172. module: knee
  173. Also see the :mod:`importers` module (which can be found
  174. in :file:`Demo/imputil/` in the Python source distribution) for additional
  175. examples.