|
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.0. |
|
11 |
|
12 |
|
13 .. index:: statement: import |
|
14 |
|
15 This 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 |
|
18 approach 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 builtin 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 |
|
103 Examples |
|
104 -------- |
|
105 |
|
106 This is a re-implementation of hierarchical module import. |
|
107 |
|
108 This 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 |
|
235 Also see the :mod:`importers` module (which can be found |
|
236 in :file:`Demo/imputil/` in the Python source distribution) for additional |
|
237 examples. |
|
238 |