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