blob: f01862df76cf66089adfb6aa5537cf39b01c9df3 [file] [log] [blame]
Guido van Rossume7e578f1995-08-04 04:00:20 +00001"""Import hook support.
2
3Consistent use of this module will make it possible to change the
4different mechanisms involved in loading modules independently.
5
6While the built-in module imp exports interfaces to the built-in
7module searching and loading algorithm, and it is possible to replace
8the built-in function __import__ in order to change the semantics of
9the import statement, until now it has been difficult to combine the
10effect of different __import__ hacks, like loading modules from URLs
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000011by rimport.py, or restricted execution by rexec.py.
Guido van Rossume7e578f1995-08-04 04:00:20 +000012
13This module defines three new concepts:
14
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000151) A "file system hooks" class provides an interface to a filesystem.
Guido van Rossume7e578f1995-08-04 04:00:20 +000016
17One hooks class is defined (Hooks), which uses the interface provided
18by standard modules os and os.path. It should be used as the base
19class for other hooks classes.
20
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000212) A "module loader" class provides an interface to to search for a
Guido van Rossume7e578f1995-08-04 04:00:20 +000022module in a search path and to load it. It defines a method which
23searches for a module in a single directory; by overriding this method
24one can redefine the details of the search. If the directory is None,
25built-in and frozen modules are searched instead.
26
27Two module loader class are defined, both implementing the search
28strategy used by the built-in __import__ function: ModuleLoader uses
29the imp module's find_module interface, while HookableModuleLoader
30uses a file system hooks class to interact with the file system. Both
31use the imp module's load_* interfaces to actually load the module.
32
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000333) A "module importer" class provides an interface to import a
Guido van Rossume7e578f1995-08-04 04:00:20 +000034module, as well as interfaces to reload and unload a module. It also
35provides interfaces to install and uninstall itself instead of the
36default __import__ and reload (and unload) functions.
37
38One module importer class is defined (ModuleImporter), which uses a
39module loader instance passed in (by default HookableModuleLoader is
40instantiated).
41
42The classes defined here should be used as base classes for extended
43functionality along those lines.
44
Skip Montanaro2dd42762001-01-23 15:35:05 +000045If a module importer class supports dotted names, its import_module()
Guido van Rossume7e578f1995-08-04 04:00:20 +000046must return a different value depending on whether it is called on
47behalf of a "from ... import ..." statement or not. (This is caused
48by the way the __import__ hook is used by the Python interpreter.) It
49would also do wise to install a different version of reload().
50
Guido van Rossume7e578f1995-08-04 04:00:20 +000051"""
52
53
54import __builtin__
55import imp
56import os
57import sys
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000058
Skip Montanaro2dd42762001-01-23 15:35:05 +000059__all__ = ["BasicModuleLoader","Hooks","ModuleLoader","FancyModuleLoader",
60 "BasicModuleImporter","ModuleImporter","install","uninstall"]
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000061
62VERBOSE = 0
Guido van Rossume7e578f1995-08-04 04:00:20 +000063
64
65from imp import C_EXTENSION, PY_SOURCE, PY_COMPILED
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000066from imp import C_BUILTIN, PY_FROZEN, PKG_DIRECTORY
67BUILTIN_MODULE = C_BUILTIN
68FROZEN_MODULE = PY_FROZEN
Guido van Rossume7e578f1995-08-04 04:00:20 +000069
70
71class _Verbose:
72
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000073 def __init__(self, verbose = VERBOSE):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000074 self.verbose = verbose
Guido van Rossume7e578f1995-08-04 04:00:20 +000075
76 def get_verbose(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000077 return self.verbose
Guido van Rossume7e578f1995-08-04 04:00:20 +000078
79 def set_verbose(self, verbose):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000080 self.verbose = verbose
Guido van Rossume7e578f1995-08-04 04:00:20 +000081
82 # XXX The following is an experimental interface
83
84 def note(self, *args):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000085 if self.verbose:
86 apply(self.message, args)
Guido van Rossume7e578f1995-08-04 04:00:20 +000087
88 def message(self, format, *args):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +000089 if args:
90 print format%args
91 else:
92 print format
Guido van Rossume7e578f1995-08-04 04:00:20 +000093
94
95class BasicModuleLoader(_Verbose):
96
97 """Basic module loader.
98
99 This provides the same functionality as built-in import. It
100 doesn't deal with checking sys.modules -- all it provides is
101 find_module() and a load_module(), as well as find_module_in_dir()
102 which searches just one directory, and can be overridden by a
103 derived class to change the module search algorithm when the basic
104 dependency on sys.path is unchanged.
105
106 The interface is a little more convenient than imp's:
107 find_module(name, [path]) returns None or 'stuff', and
108 load_module(name, stuff) loads the module.
109
110 """
111
112 def find_module(self, name, path = None):
Tim Peters07e99cb2001-01-14 23:47:14 +0000113 if path is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000114 path = [None] + self.default_path()
115 for dir in path:
116 stuff = self.find_module_in_dir(name, dir)
117 if stuff: return stuff
118 return None
Guido van Rossume7e578f1995-08-04 04:00:20 +0000119
120 def default_path(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000121 return sys.path
Guido van Rossume7e578f1995-08-04 04:00:20 +0000122
123 def find_module_in_dir(self, name, dir):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000124 if dir is None:
125 return self.find_builtin_module(name)
126 else:
127 try:
128 return imp.find_module(name, [dir])
129 except ImportError:
130 return None
Guido van Rossume7e578f1995-08-04 04:00:20 +0000131
132 def find_builtin_module(self, name):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000133 # XXX frozen packages?
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000134 if imp.is_builtin(name):
135 return None, '', ('', '', BUILTIN_MODULE)
136 if imp.is_frozen(name):
137 return None, '', ('', '', FROZEN_MODULE)
138 return None
Guido van Rossume7e578f1995-08-04 04:00:20 +0000139
140 def load_module(self, name, stuff):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000141 file, filename, info = stuff
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000142 try:
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000143 return imp.load_module(name, file, filename, info)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000144 finally:
145 if file: file.close()
Guido van Rossume7e578f1995-08-04 04:00:20 +0000146
147
148class Hooks(_Verbose):
149
150 """Hooks into the filesystem and interpreter.
151
152 By deriving a subclass you can redefine your filesystem interface,
153 e.g. to merge it with the URL space.
154
155 This base class behaves just like the native filesystem.
156
157 """
158
159 # imp interface
160 def get_suffixes(self): return imp.get_suffixes()
161 def new_module(self, name): return imp.new_module(name)
162 def is_builtin(self, name): return imp.is_builtin(name)
163 def init_builtin(self, name): return imp.init_builtin(name)
164 def is_frozen(self, name): return imp.is_frozen(name)
165 def init_frozen(self, name): return imp.init_frozen(name)
166 def get_frozen_object(self, name): return imp.get_frozen_object(name)
167 def load_source(self, name, filename, file=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000168 return imp.load_source(name, filename, file)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000169 def load_compiled(self, name, filename, file=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000170 return imp.load_compiled(name, filename, file)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000171 def load_dynamic(self, name, filename, file=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000172 return imp.load_dynamic(name, filename, file)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000173 def load_package(self, name, filename, file=None):
174 return imp.load_module(name, file, filename, ("", "", PKG_DIRECTORY))
Guido van Rossume7e578f1995-08-04 04:00:20 +0000175
176 def add_module(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000177 d = self.modules_dict()
Raymond Hettinger54f02222002-06-01 14:18:47 +0000178 if name in d: return d[name]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000179 d[name] = m = self.new_module(name)
180 return m
Guido van Rossume7e578f1995-08-04 04:00:20 +0000181
182 # sys interface
183 def modules_dict(self): return sys.modules
184 def default_path(self): return sys.path
185
186 def path_split(self, x): return os.path.split(x)
187 def path_join(self, x, y): return os.path.join(x, y)
188 def path_isabs(self, x): return os.path.isabs(x)
189 # etc.
190
191 def path_exists(self, x): return os.path.exists(x)
192 def path_isdir(self, x): return os.path.isdir(x)
193 def path_isfile(self, x): return os.path.isfile(x)
194 def path_islink(self, x): return os.path.islink(x)
195 # etc.
196
197 def openfile(self, *x): return apply(open, x)
198 openfile_error = IOError
199 def listdir(self, x): return os.listdir(x)
200 listdir_error = os.error
201 # etc.
202
203
204class ModuleLoader(BasicModuleLoader):
205
206 """Default module loader; uses file system hooks.
207
208 By defining suitable hooks, you might be able to load modules from
209 other sources than the file system, e.g. from compressed or
210 encrypted files, tar files or (if you're brave!) URLs.
211
212 """
213
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000214 def __init__(self, hooks = None, verbose = VERBOSE):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000215 BasicModuleLoader.__init__(self, verbose)
216 self.hooks = hooks or Hooks(verbose)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000217
218 def default_path(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000219 return self.hooks.default_path()
Guido van Rossume7e578f1995-08-04 04:00:20 +0000220
221 def modules_dict(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000222 return self.hooks.modules_dict()
Guido van Rossume7e578f1995-08-04 04:00:20 +0000223
224 def get_hooks(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000225 return self.hooks
Guido van Rossume7e578f1995-08-04 04:00:20 +0000226
227 def set_hooks(self, hooks):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000228 self.hooks = hooks
Guido van Rossume7e578f1995-08-04 04:00:20 +0000229
230 def find_builtin_module(self, name):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000231 # XXX frozen packages?
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000232 if self.hooks.is_builtin(name):
233 return None, '', ('', '', BUILTIN_MODULE)
234 if self.hooks.is_frozen(name):
235 return None, '', ('', '', FROZEN_MODULE)
236 return None
Guido van Rossume7e578f1995-08-04 04:00:20 +0000237
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000238 def find_module_in_dir(self, name, dir, allow_packages=1):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000239 if dir is None:
240 return self.find_builtin_module(name)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000241 if allow_packages:
242 fullname = self.hooks.path_join(dir, name)
243 if self.hooks.path_isdir(fullname):
244 stuff = self.find_module_in_dir("__init__", fullname, 0)
245 if stuff:
246 file = stuff[0]
247 if file: file.close()
248 return None, fullname, ('', '', PKG_DIRECTORY)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000249 for info in self.hooks.get_suffixes():
250 suff, mode, type = info
251 fullname = self.hooks.path_join(dir, name+suff)
252 try:
253 fp = self.hooks.openfile(fullname, mode)
254 return fp, fullname, info
255 except self.hooks.openfile_error:
256 pass
257 return None
Guido van Rossume7e578f1995-08-04 04:00:20 +0000258
259 def load_module(self, name, stuff):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000260 file, filename, info = stuff
261 (suff, mode, type) = info
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000262 try:
263 if type == BUILTIN_MODULE:
264 return self.hooks.init_builtin(name)
265 if type == FROZEN_MODULE:
266 return self.hooks.init_frozen(name)
267 if type == C_EXTENSION:
268 m = self.hooks.load_dynamic(name, filename, file)
269 elif type == PY_SOURCE:
270 m = self.hooks.load_source(name, filename, file)
271 elif type == PY_COMPILED:
272 m = self.hooks.load_compiled(name, filename, file)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000273 elif type == PKG_DIRECTORY:
274 m = self.hooks.load_package(name, filename, file)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000275 else:
276 raise ImportError, "Unrecognized module type (%s) for %s" % \
277 (`type`, name)
278 finally:
279 if file: file.close()
280 m.__file__ = filename
281 return m
Guido van Rossume7e578f1995-08-04 04:00:20 +0000282
283
284class FancyModuleLoader(ModuleLoader):
285
286 """Fancy module loader -- parses and execs the code itself."""
287
288 def load_module(self, name, stuff):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000289 file, filename, (suff, mode, type) = stuff
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000290 realfilename = filename
291 path = None
292
293 if type == PKG_DIRECTORY:
294 initstuff = self.find_module_in_dir("__init__", filename, 0)
295 if not initstuff:
296 raise ImportError, "No __init__ module in package %s" % name
297 initfile, initfilename, initinfo = initstuff
298 initsuff, initmode, inittype = initinfo
299 if inittype not in (PY_COMPILED, PY_SOURCE):
300 if initfile: initfile.close()
301 raise ImportError, \
302 "Bad type (%s) for __init__ module in package %s" % (
303 `inittype`, name)
304 path = [filename]
305 file = initfile
306 realfilename = initfilename
307 type = inittype
308
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000309 if type == FROZEN_MODULE:
310 code = self.hooks.get_frozen_object(name)
311 elif type == PY_COMPILED:
312 import marshal
313 file.seek(8)
314 code = marshal.load(file)
315 elif type == PY_SOURCE:
316 data = file.read()
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000317 code = compile(data, realfilename, 'exec')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000318 else:
319 return ModuleLoader.load_module(self, name, stuff)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000320
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000321 m = self.hooks.add_module(name)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000322 if path:
323 m.__path__ = path
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000324 m.__file__ = filename
325 exec code in m.__dict__
326 return m
Guido van Rossume7e578f1995-08-04 04:00:20 +0000327
328
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000329class BasicModuleImporter(_Verbose):
Guido van Rossume7e578f1995-08-04 04:00:20 +0000330
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000331 """Basic module importer; uses module loader.
Guido van Rossume7e578f1995-08-04 04:00:20 +0000332
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000333 This provides basic import facilities but no package imports.
Guido van Rossume7e578f1995-08-04 04:00:20 +0000334
335 """
336
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000337 def __init__(self, loader = None, verbose = VERBOSE):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000338 _Verbose.__init__(self, verbose)
339 self.loader = loader or ModuleLoader(None, verbose)
340 self.modules = self.loader.modules_dict()
Guido van Rossume7e578f1995-08-04 04:00:20 +0000341
342 def get_loader(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000343 return self.loader
Guido van Rossume7e578f1995-08-04 04:00:20 +0000344
345 def set_loader(self, loader):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000346 self.loader = loader
Guido van Rossume7e578f1995-08-04 04:00:20 +0000347
348 def get_hooks(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000349 return self.loader.get_hooks()
Guido van Rossume7e578f1995-08-04 04:00:20 +0000350
351 def set_hooks(self, hooks):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000352 return self.loader.set_hooks(hooks)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000353
354 def import_module(self, name, globals={}, locals={}, fromlist=[]):
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000355 name = str(name)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000356 if name in self.modules:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000357 return self.modules[name] # Fast path
358 stuff = self.loader.find_module(name)
359 if not stuff:
360 raise ImportError, "No module named %s" % name
361 return self.loader.load_module(name, stuff)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000362
363 def reload(self, module, path = None):
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000364 name = str(module.__name__)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000365 stuff = self.loader.find_module(name, path)
366 if not stuff:
367 raise ImportError, "Module %s not found for reload" % name
368 return self.loader.load_module(name, stuff)
Guido van Rossume7e578f1995-08-04 04:00:20 +0000369
370 def unload(self, module):
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000371 del self.modules[str(module.__name__)]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000372 # XXX Should this try to clear the module's namespace?
Guido van Rossume7e578f1995-08-04 04:00:20 +0000373
374 def install(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000375 self.save_import_module = __builtin__.__import__
376 self.save_reload = __builtin__.reload
377 if not hasattr(__builtin__, 'unload'):
378 __builtin__.unload = None
379 self.save_unload = __builtin__.unload
380 __builtin__.__import__ = self.import_module
381 __builtin__.reload = self.reload
382 __builtin__.unload = self.unload
Guido van Rossume7e578f1995-08-04 04:00:20 +0000383
384 def uninstall(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000385 __builtin__.__import__ = self.save_import_module
386 __builtin__.reload = self.save_reload
387 __builtin__.unload = self.save_unload
388 if not __builtin__.unload:
389 del __builtin__.unload
Guido van Rossume7e578f1995-08-04 04:00:20 +0000390
391
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000392class ModuleImporter(BasicModuleImporter):
393
394 """A module importer that supports packages."""
Tim Peters07e99cb2001-01-14 23:47:14 +0000395
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000396 def import_module(self, name, globals=None, locals=None, fromlist=None):
397 parent = self.determine_parent(globals)
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000398 q, tail = self.find_head_package(parent, str(name))
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000399 m = self.load_tail(q, tail)
400 if not fromlist:
401 return q
402 if hasattr(m, "__path__"):
403 self.ensure_fromlist(m, fromlist)
404 return m
405
406 def determine_parent(self, globals):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000407 if not globals or not "__name__" in globals:
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000408 return None
409 pname = globals['__name__']
Raymond Hettinger54f02222002-06-01 14:18:47 +0000410 if "__path__" in globals:
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000411 parent = self.modules[pname]
412 assert globals is parent.__dict__
413 return parent
414 if '.' in pname:
Eric S. Raymondbf97c9d2001-02-09 10:18:37 +0000415 i = pname.rfind('.')
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000416 pname = pname[:i]
417 parent = self.modules[pname]
418 assert parent.__name__ == pname
419 return parent
420 return None
421
422 def find_head_package(self, parent, name):
423 if '.' in name:
Eric S. Raymondbf97c9d2001-02-09 10:18:37 +0000424 i = name.find('.')
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000425 head = name[:i]
426 tail = name[i+1:]
427 else:
428 head = name
429 tail = ""
430 if parent:
431 qname = "%s.%s" % (parent.__name__, head)
432 else:
433 qname = head
434 q = self.import_it(head, qname, parent)
435 if q: return q, tail
436 if parent:
437 qname = head
438 parent = None
439 q = self.import_it(head, qname, parent)
440 if q: return q, tail
441 raise ImportError, "No module named " + qname
442
443 def load_tail(self, q, tail):
444 m = q
445 while tail:
Eric S. Raymondbf97c9d2001-02-09 10:18:37 +0000446 i = tail.find('.')
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000447 if i < 0: i = len(tail)
448 head, tail = tail[:i], tail[i+1:]
449 mname = "%s.%s" % (m.__name__, head)
450 m = self.import_it(head, mname, m)
451 if not m:
452 raise ImportError, "No module named " + mname
453 return m
454
455 def ensure_fromlist(self, m, fromlist, recursive=0):
456 for sub in fromlist:
457 if sub == "*":
458 if not recursive:
459 try:
460 all = m.__all__
461 except AttributeError:
462 pass
463 else:
464 self.ensure_fromlist(m, all, 1)
465 continue
466 if sub != "*" and not hasattr(m, sub):
467 subname = "%s.%s" % (m.__name__, sub)
468 submod = self.import_it(sub, subname, m)
469 if not submod:
470 raise ImportError, "No module named " + subname
471
Fred Drake8deeced2000-04-13 14:52:27 +0000472 def import_it(self, partname, fqname, parent, force_load=0):
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000473 if not partname:
474 raise ValueError, "Empty module name"
Fred Drake8deeced2000-04-13 14:52:27 +0000475 if not force_load:
476 try:
477 return self.modules[fqname]
478 except KeyError:
479 pass
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000480 try:
481 path = parent and parent.__path__
482 except AttributeError:
483 return None
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000484 partname = str(partname)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000485 stuff = self.loader.find_module(partname, path)
486 if not stuff:
487 return None
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000488 fqname = str(fqname)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000489 m = self.loader.load_module(fqname, stuff)
490 if parent:
491 setattr(parent, partname, m)
492 return m
493
494 def reload(self, module):
Gustavo Niemeyerd5ae01a2002-12-16 13:11:57 +0000495 name = str(module.__name__)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000496 if '.' not in name:
Fred Drake8deeced2000-04-13 14:52:27 +0000497 return self.import_it(name, name, None, force_load=1)
Eric S. Raymondbf97c9d2001-02-09 10:18:37 +0000498 i = name.rfind('.')
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000499 pname = name[:i]
500 parent = self.modules[pname]
Fred Drake8deeced2000-04-13 14:52:27 +0000501 return self.import_it(name[i+1:], name, parent, force_load=1)
Guido van Rossum9f5c36f1998-06-29 20:31:16 +0000502
503
Guido van Rossume7e578f1995-08-04 04:00:20 +0000504default_importer = None
505current_importer = None
506
507def install(importer = None):
508 global current_importer
509 current_importer = importer or default_importer or ModuleImporter()
510 current_importer.install()
511
512def uninstall():
513 global current_importer
514 current_importer.uninstall()