blob: 6a50b7a5df683cba7869355691dc63965f457397 [file] [log] [blame]
Sean Reifscheider99cafb92007-08-28 09:07:54 +00001
2:mod:`imputil` --- Import utilities
3=====================================================
4
5.. module:: imputil
Georg Brandl23b8ddc2007-08-28 10:48:18 +00006 :synopsis: Manage and augment the import process.
Brett Cannon80bb9d92008-05-08 18:15:14 +00007 :deprecated:
8
9.. deprecated:: 2.6
Brett Cannona975cd42008-05-11 01:06:54 +000010 The :mod:`imputil` module has been removed in Python 3.0.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000011
12
13.. index:: statement: import
14
15This module provides a very handy and useful mechanism for custom
Georg Brandl23b8ddc2007-08-28 10:48:18 +000016: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.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000019
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
Georg Brandl23b8ddc2007-08-28 10:48:18 +000050 *parent* specifies a parent module to define a context for importing.
51 It may be ``None``, indicating no particular context for the search.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000052
Georg Brandl23b8ddc2007-08-28 10:48:18 +000053 *modname* specifies a single module (not dotted) within the parent.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000054
Georg Brandl23b8ddc2007-08-28 10:48:18 +000055 *fqname* specifies the fully-qualified module name. This is a
Sean Reifscheider99cafb92007-08-28 09:07:54 +000056 (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
Georg Brandl23b8ddc2007-08-28 10:48:18 +000061 This method should return ``None``, or a 3-tuple.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000062
Georg Brandl23b8ddc2007-08-28 10:48:18 +000063 * If the module was not found, then ``None`` should be returned.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000064
65 * The first item of the 2- or 3-tuple should be the integer 0 or 1,
Georg Brandl23b8ddc2007-08-28 10:48:18 +000066 specifying whether the module that was found is a package or not.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000067
68 * The second item is the code object for the module (it will be
Georg Brandl23b8ddc2007-08-28 10:48:18 +000069 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).
Sean Reifscheider99cafb92007-08-28 09:07:54 +000071
72 * The third item is a dictionary of name/value pairs that will be
Georg Brandl23b8ddc2007-08-28 10:48:18 +000073 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.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000078
79
80.. class:: BuiltinImporter()
81
82 Emulate the import mechanism for builtin and frozen modules. This is a
Georg Brandl23b8ddc2007-08-28 10:48:18 +000083 sub-class of the :class:`Importer` class.
Sean Reifscheider99cafb92007-08-28 09:07:54 +000084
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 klunkier predecessor of this module, "ni".)
112
Georg Brandl23b8ddc2007-08-28 10:48:18 +0000113::
Sean Reifscheider99cafb92007-08-28 09:07:54 +0000114
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