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