blob: d36d1a012a5f0190aebe9c9349cbdc093a0b1b73 [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
Benjamin Peterson90f36732008-07-12 20:16:19 +0000111(The name is a pun on the clunkier predecessor of this module, "ni".)
Sean Reifscheider99cafb92007-08-28 09:07:54 +0000112
Georg Brandl23b8ddc2007-08-28 10:48:18 +0000113::
Sean Reifscheider99cafb92007-08-28 09:07:54 +0000114
Jeroen Ruigrok van der Werven51497422009-02-19 18:52:21 +0000115 import __builtin__
116 import imp
117 import sys
Sean Reifscheider99cafb92007-08-28 09:07:54 +0000118
119 # Replacement for __import__()
120 def import_hook(name, globals=None, locals=None, fromlist=None):
121 parent = determine_parent(globals)
122 q, tail = find_head_package(parent, name)
123 m = load_tail(q, tail)
124 if not fromlist:
125 return q
126 if hasattr(m, "__path__"):
127 ensure_fromlist(m, fromlist)
128 return m
129
130 def determine_parent(globals):
131 if not globals or not globals.has_key("__name__"):
132 return None
133 pname = globals['__name__']
134 if globals.has_key("__path__"):
135 parent = sys.modules[pname]
136 assert globals is parent.__dict__
137 return parent
138 if '.' in pname:
139 i = pname.rfind('.')
140 pname = pname[:i]
141 parent = sys.modules[pname]
142 assert parent.__name__ == pname
143 return parent
144 return None
145
146 def find_head_package(parent, name):
147 if '.' in name:
148 i = name.find('.')
149 head = name[:i]
150 tail = name[i+1:]
151 else:
152 head = name
153 tail = ""
154 if parent:
155 qname = "%s.%s" % (parent.__name__, head)
156 else:
157 qname = head
158 q = import_module(head, qname, parent)
159 if q: return q, tail
160 if parent:
161 qname = head
162 parent = None
163 q = import_module(head, qname, parent)
164 if q: return q, tail
165 raise ImportError, "No module named " + qname
166
167 def load_tail(q, tail):
168 m = q
169 while tail:
170 i = tail.find('.')
171 if i < 0: i = len(tail)
172 head, tail = tail[:i], tail[i+1:]
173 mname = "%s.%s" % (m.__name__, head)
174 m = import_module(head, mname, m)
175 if not m:
176 raise ImportError, "No module named " + mname
177 return m
178
179 def ensure_fromlist(m, fromlist, recursive=0):
180 for sub in fromlist:
181 if sub == "*":
182 if not recursive:
183 try:
184 all = m.__all__
185 except AttributeError:
186 pass
187 else:
188 ensure_fromlist(m, all, 1)
189 continue
190 if sub != "*" and not hasattr(m, sub):
191 subname = "%s.%s" % (m.__name__, sub)
192 submod = import_module(sub, subname, m)
193 if not submod:
194 raise ImportError, "No module named " + subname
195
196 def import_module(partname, fqname, parent):
197 try:
198 return sys.modules[fqname]
199 except KeyError:
200 pass
201 try:
202 fp, pathname, stuff = imp.find_module(partname,
203 parent and parent.__path__)
204 except ImportError:
205 return None
206 try:
207 m = imp.load_module(fqname, fp, pathname, stuff)
208 finally:
209 if fp: fp.close()
210 if parent:
211 setattr(parent, partname, m)
212 return m
213
214
215 # Replacement for reload()
216 def reload_hook(module):
217 name = module.__name__
218 if '.' not in name:
219 return import_module(name, name, None)
220 i = name.rfind('.')
221 pname = name[:i]
222 parent = sys.modules[pname]
223 return import_module(name[i+1:], name, parent)
224
225
226 # Save the original hooks
227 original_import = __builtin__.__import__
228 original_reload = __builtin__.reload
229
230 # Now install our hooks
231 __builtin__.__import__ = import_hook
232 __builtin__.reload = reload_hook
233
234.. index::
235 module: knee
236
237Also see the :mod:`importers` module (which can be found
238in :file:`Demo/imputil/` in the Python source distribution) for additional
239examples.
240