1 """Utilities to support packages."""
3 # NOTE: This module must remain compatible with Python 2.3, as it is shared
4 # by setuptools for distribution with Python 2.3 and up.
10 from types
import ModuleType
13 'get_importer', 'iter_importers', 'get_loader', 'find_loader',
14 'walk_packages', 'iter_modules',
15 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
18 def read_code(stream
):
19 # This helper is needed in order for the PEP 302 emulation to
20 # correctly handle compiled files
23 magic
= stream
.read(4)
24 if magic
!= imp
.get_magic():
27 stream
.read(4) # Skip timestamp
28 return marshal
.load(stream
)
31 def simplegeneric(func
):
32 """Make a trivial single-dispatch generic function"""
34 def wrapper(*args
, **kw
):
38 except AttributeError:
42 except AttributeError:
44 class cls(cls
, object):
48 mro
= object, # must be an ExtensionClass or some such :(
51 return registry
[t
](*args
, **kw
)
53 return func(*args
, **kw
)
55 wrapper
.__name
__ = func
.__name
__
56 except (TypeError, AttributeError):
57 pass # Python 2.3 doesn't allow functions to be renamed
59 def register(typ
, func
=None):
61 return lambda f
: register(typ
, f
)
65 wrapper
.__dict
__ = func
.__dict
__
66 wrapper
.__doc
__ = func
.__doc
__
67 wrapper
.register
= register
71 def walk_packages(path
=None, prefix
='', onerror
=None):
72 """Yield submodule names+loaders recursively, for path or sys.path"""
79 for importer
, name
, ispkg
in iter_modules(path
, prefix
):
80 yield importer
, name
, ispkg
86 if onerror
is not None:
89 path
= getattr(sys
.modules
[name
], '__path__', None) or []
91 # don't traverse path items we've seen before
92 path
= [p
for p
in path
if not seen(p
)]
94 for item
in walk_packages(path
, name
+'.'):
98 def iter_modules(path
=None, prefix
=''):
99 """Yield submodule names+loaders for path or sys.path"""
101 importers
= iter_importers()
103 importers
= map(get_importer
, path
)
107 for name
, ispkg
in iter_importer_modules(i
, prefix
):
108 if name
not in yielded
:
114 def iter_importer_modules(importer
, prefix
=''):
115 if not hasattr(importer
, 'iter_modules'):
117 return importer
.iter_modules(prefix
)
119 iter_importer_modules
= simplegeneric(iter_importer_modules
)
123 """PEP 302 Importer that wraps Python's "classic" import algorithm
125 ImpImporter(dirname) produces a PEP 302 importer that searches that
126 directory. ImpImporter(None) produces a PEP 302 importer that searches
127 the current sys.path, plus any modules that are frozen or built-in.
129 Note that ImpImporter does not currently support being used by placement
133 def __init__(self
, path
=None):
136 def find_module(self
, fullname
, path
=None):
137 # Note: we ignore 'path' argument since it is only used via meta_path
138 subname
= fullname
.split(".")[-1]
139 if subname
!= fullname
and self
.path
is None:
141 if self
.path
is None:
144 path
= [os
.path
.realpath(self
.path
)]
146 file, filename
, etc
= imp
.find_module(subname
, path
)
149 return ImpLoader(fullname
, file, filename
, etc
)
151 def iter_modules(self
, prefix
=''):
152 if self
.path
is None or not os
.path
.isdir(self
.path
):
158 filenames
= os
.listdir(self
.path
)
159 filenames
.sort() # handle packages before same-named modules
162 modname
= inspect
.getmodulename(fn
)
163 if modname
=='__init__' or modname
in yielded
:
166 path
= os
.path
.join(self
.path
, fn
)
169 if not modname
and os
.path
.isdir(path
) and '.' not in fn
:
171 for fn
in os
.listdir(path
):
172 subname
= inspect
.getmodulename(fn
)
173 if subname
=='__init__':
177 continue # not a package
179 if modname
and '.' not in modname
:
181 yield prefix
+ modname
, ispkg
185 """PEP 302 Loader that wraps Python's "classic" import algorithm
189 def __init__(self
, fullname
, file, filename
, etc
):
191 self
.filename
= filename
192 self
.fullname
= fullname
195 def load_module(self
, fullname
):
198 mod
= imp
.load_module(fullname
, self
.file, self
.filename
, self
.etc
)
202 # Note: we don't set __loader__ because we want the module to look
203 # normal; i.e. this is just a wrapper for standard import machinery
206 def get_data(self
, pathname
):
207 return open(pathname
, "rb").read()
210 if self
.file and self
.file.closed
:
211 mod_type
= self
.etc
[2]
212 if mod_type
==imp
.PY_SOURCE
:
213 self
.file = open(self
.filename
, 'rU')
214 elif mod_type
in (imp
.PY_COMPILED
, imp
.C_EXTENSION
):
215 self
.file = open(self
.filename
, 'rb')
217 def _fix_name(self
, fullname
):
219 fullname
= self
.fullname
220 elif fullname
!= self
.fullname
:
221 raise ImportError("Loader for module %s cannot handle "
222 "module %s" % (self
.fullname
, fullname
))
225 def is_package(self
, fullname
):
226 fullname
= self
._fix
_name
(fullname
)
227 return self
.etc
[2]==imp
.PKG_DIRECTORY
229 def get_code(self
, fullname
=None):
230 fullname
= self
._fix
_name
(fullname
)
231 if self
.code
is None:
232 mod_type
= self
.etc
[2]
233 if mod_type
==imp
.PY_SOURCE
:
234 source
= self
.get_source(fullname
)
235 self
.code
= compile(source
, self
.filename
, 'exec')
236 elif mod_type
==imp
.PY_COMPILED
:
239 self
.code
= read_code(self
.file)
242 elif mod_type
==imp
.PKG_DIRECTORY
:
243 self
.code
= self
._get
_delegate
().get_code()
246 def get_source(self
, fullname
=None):
247 fullname
= self
._fix
_name
(fullname
)
248 if self
.source
is None:
249 mod_type
= self
.etc
[2]
250 if mod_type
==imp
.PY_SOURCE
:
253 self
.source
= self
.file.read()
256 elif mod_type
==imp
.PY_COMPILED
:
257 if os
.path
.exists(self
.filename
[:-1]):
258 f
= open(self
.filename
[:-1], 'rU')
259 self
.source
= f
.read()
261 elif mod_type
==imp
.PKG_DIRECTORY
:
262 self
.source
= self
._get
_delegate
().get_source()
266 def _get_delegate(self
):
267 return ImpImporter(self
.filename
).find_module('__init__')
269 def get_filename(self
, fullname
=None):
270 fullname
= self
._fix
_name
(fullname
)
271 mod_type
= self
.etc
[2]
272 if self
.etc
[2]==imp
.PKG_DIRECTORY
:
273 return self
._get
_delegate
().get_filename()
274 elif self
.etc
[2] in (imp
.PY_SOURCE
, imp
.PY_COMPILED
, imp
.C_EXTENSION
):
281 from zipimport
import zipimporter
283 def iter_zipimport_modules(importer
, prefix
=''):
284 dirlist
= zipimport
._zip
_directory
_cache
[importer
.archive
].keys()
286 _prefix
= importer
.prefix
291 if not fn
.startswith(_prefix
):
294 fn
= fn
[plen
:].split(os
.sep
)
296 if len(fn
)==2 and fn
[1].startswith('__init__.py'):
297 if fn
[0] not in yielded
:
304 modname
= inspect
.getmodulename(fn
[0])
305 if modname
=='__init__':
308 if modname
and '.' not in modname
and modname
not in yielded
:
310 yield prefix
+ modname
, False
312 iter_importer_modules
.register(zipimporter
, iter_zipimport_modules
)
318 def get_importer(path_item
):
319 """Retrieve a PEP 302 importer for the given path item
321 The returned importer is cached in sys.path_importer_cache
322 if it was newly created by a path hook.
324 If there is no importer, a wrapper around the basic import
325 machinery is returned. This wrapper is never inserted into
326 the importer cache (None is inserted instead).
328 The cache (or part of it) can be cleared manually if a
329 rescan of sys.path_hooks is necessary.
332 importer
= sys
.path_importer_cache
[path_item
]
334 for path_hook
in sys
.path_hooks
:
336 importer
= path_hook(path_item
)
342 sys
.path_importer_cache
.setdefault(path_item
, importer
)
344 # The boolean values are used for caching valid and invalid
345 # file paths for the built-in import machinery
346 if importer
in (None, True, False):
348 importer
= ImpImporter(path_item
)
354 def iter_importers(fullname
=""):
355 """Yield PEP 302 importers for the given module name
357 If fullname contains a '.', the importers will be for the package
358 containing fullname, otherwise they will be importers for sys.meta_path,
359 sys.path, and Python's "classic" import machinery, in that order. If
360 the named module is in a package, that package is imported as a side
361 effect of invoking this function.
363 Non PEP 302 mechanisms (e.g. the Windows registry) used by the
364 standard import machinery to find files in alternative locations
365 are partially supported, but are searched AFTER sys.path. Normally,
366 these locations are searched BEFORE sys.path, preventing sys.path
367 entries from shadowing them.
369 For this to cause a visible difference in behaviour, there must
370 be a module or package name that is accessible via both sys.path
371 and one of the non PEP 302 file system mechanisms. In this case,
372 the emulation will find the former version, while the builtin
373 import mechanism will find the latter.
375 Items of the following types can be affected by this discrepancy:
376 imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY
378 if fullname
.startswith('.'):
379 raise ImportError("Relative module names not supported")
381 # Get the containing package's __path__
382 pkg
= '.'.join(fullname
.split('.')[:-1])
383 if pkg
not in sys
.modules
:
385 path
= getattr(sys
.modules
[pkg
], '__path__', None) or []
387 for importer
in sys
.meta_path
:
391 yield get_importer(item
)
392 if '.' not in fullname
:
395 def get_loader(module_or_name
):
396 """Get a PEP 302 "loader" object for module_or_name
398 If the module or package is accessible via the normal import
399 mechanism, a wrapper around the relevant part of that machinery
400 is returned. Returns None if the module cannot be found or imported.
401 If the named module is not already imported, its containing package
402 (if any) is imported, in order to establish the package __path__.
404 This function uses iter_importers(), and is thus subject to the same
405 limitations regarding platform-specific special import locations such
406 as the Windows registry.
408 if module_or_name
in sys
.modules
:
409 module_or_name
= sys
.modules
[module_or_name
]
410 if isinstance(module_or_name
, ModuleType
):
411 module
= module_or_name
412 loader
= getattr(module
, '__loader__', None)
413 if loader
is not None:
415 fullname
= module
.__name
__
417 fullname
= module_or_name
418 return find_loader(fullname
)
420 def find_loader(fullname
):
421 """Find a PEP 302 "loader" object for fullname
423 If fullname contains dots, path must be the containing package's __path__.
424 Returns None if the module cannot be found or imported. This function uses
425 iter_importers(), and is thus subject to the same limitations regarding
426 platform-specific special import locations such as the Windows registry.
428 for importer
in iter_importers(fullname
):
429 loader
= importer
.find_module(fullname
)
430 if loader
is not None:
436 def extend_path(path
, name
):
437 """Extend a package's path.
439 Intended use is to place the following code in a package's __init__.py:
441 from pkgutil import extend_path
442 __path__ = extend_path(__path__, __name__)
444 This will add to the package's __path__ all subdirectories of
445 directories on sys.path named after the package. This is useful
446 if one wants to distribute different parts of a single logical
447 package as multiple directories.
449 It also looks for *.pkg files beginning where * matches the name
450 argument. This feature is similar to *.pth files (see site.py),
451 except that it doesn't special-case lines starting with 'import'.
452 A *.pkg file is trusted at face value: apart from checking for
453 duplicates, all entries found in a *.pkg file are added to the
454 path, regardless of whether they are exist the filesystem. (This
457 If the input path is not a list (as is the case for frozen
458 packages) it is returned unchanged. The input path is not
459 modified; an extended copy is returned. Items are only appended
460 to the copy at the end.
462 It is assumed that sys.path is a sequence. Items of sys.path that
463 are not (unicode or 8-bit) strings referring to existing
464 directories are ignored. Unicode items of sys.path that cause
465 errors when used as filenames may cause this function to raise an
466 exception (in line with os.path.isdir() behavior).
469 if not isinstance(path
, list):
470 # This could happen e.g. when this is called from inside a
471 # frozen package. Return the path unchanged in that case.
474 pname
= os
.path
.join(*name
.split('.')) # Reconstitute as relative path
475 # Just in case os.extsep != '.'
476 sname
= os
.extsep
.join(name
.split('.'))
477 sname_pkg
= sname
+ os
.extsep
+ "pkg"
478 init_py
= "__init__" + os
.extsep
+ "py"
480 path
= path
[:] # Start with a copy of the existing path
483 if not isinstance(dir, basestring
) or not os
.path
.isdir(dir):
485 subdir
= os
.path
.join(dir, pname
)
486 # XXX This may still add duplicate entries to path on
487 # case-insensitive filesystems
488 initfile
= os
.path
.join(subdir
, init_py
)
489 if subdir
not in path
and os
.path
.isfile(initfile
):
491 # XXX Is this the right thing for subpackages like zope.app?
492 # It looks for a file named "zope.app.pkg"
493 pkgfile
= os
.path
.join(dir, sname_pkg
)
494 if os
.path
.isfile(pkgfile
):
498 sys
.stderr
.write("Can't open %s: %s\n" %
502 line
= line
.rstrip('\n')
503 if not line
or line
.startswith('#'):
505 path
.append(line
) # Don't check for existence!