12 PEP 302: New Import Hooks
While it's been possible to write custom import hooks ever since the ihooks
module was introduced in Python 1.3, no one has ever been really happy with it because
writing new import hooks is difficult and messy. There have been various proposed
alternatives such as the imputil and iu
modules, but none of them has ever gained much acceptance, and none of them were easily
usable from C code.
PEP 302
borrows ideas from its predecessors, especially from Gordon McMillan's iu
module. Three new items are added to the sys module:
sys.path_hooks is a list of callable objects; most often they'll be
classes. Each callable takes a string containing a path and either returns an importer
object that will handle imports from this path or raises an ImportError
exception if it can't handle this path.
sys.path_importer_cache caches importer objects for each path, so sys.path_hooks
will only need to be traversed once for each path.
sys.meta_path is a list of importer objects that will be traversed
before sys.path is checked. This list is initially empty, but user code
can add objects to it. Additional built-in and frozen modules can be imported by an
object added to this list.
Importer objects must have a single method, find_module(fullname,
path=None). fullname will be a module or package name, e.g.
"string" or "distutils.core".
find_module() must return a loader object that has a single
method, load_module(fullname), that creates and returns
the corresponding module object.
Pseudo-code for Python's new import logic, therefore, looks something like this
(simplified a bit; see PEP 302 for the full details):
for mp in sys.meta_path:
loader = mp(fullname)
if loader is not None:
<module> = loader.load_module(fullname)
for path in sys.path:
for hook in sys.path_hooks:
try:
importer = hook(path)
except ImportError:
# ImportError, so try the other path hooks
pass
else:
loader = importer.find_module(fullname)
<module> = loader.load_module(fullname)
# Not found!
raise ImportError
|