mirror of
https://github.com/python/cpython.git
synced 2025-09-18 14:40:43 +00:00
parent
8e7cdb2586
commit
d5f9223981
5 changed files with 35 additions and 21 deletions
|
@ -1,5 +1,6 @@
|
|||
"""Utilities to support packages."""
|
||||
|
||||
from collections import namedtuple
|
||||
from functools import singledispatch as simplegeneric
|
||||
import importlib
|
||||
import importlib.util
|
||||
|
@ -14,9 +15,14 @@ __all__ = [
|
|||
'get_importer', 'iter_importers', 'get_loader', 'find_loader',
|
||||
'walk_packages', 'iter_modules', 'get_data',
|
||||
'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
|
||||
'ModuleInfo',
|
||||
]
|
||||
|
||||
|
||||
ModuleInfo = namedtuple('ModuleInfo', 'module_finder name ispkg')
|
||||
ModuleInfo.__doc__ = 'A namedtuple with minimal info about a module.'
|
||||
|
||||
|
||||
def _get_spec(finder, name):
|
||||
"""Return the finder-specific module spec."""
|
||||
# Works with legacy finders.
|
||||
|
@ -45,7 +51,7 @@ def read_code(stream):
|
|||
|
||||
|
||||
def walk_packages(path=None, prefix='', onerror=None):
|
||||
"""Yields (module_finder, name, ispkg) for all modules recursively
|
||||
"""Yields ModuleInfo for all modules recursively
|
||||
on path, or, if path is None, all accessible modules.
|
||||
|
||||
'path' should be either None or a list of paths to look for
|
||||
|
@ -78,31 +84,31 @@ def walk_packages(path=None, prefix='', onerror=None):
|
|||
return True
|
||||
m[p] = True
|
||||
|
||||
for importer, name, ispkg in iter_modules(path, prefix):
|
||||
yield importer, name, ispkg
|
||||
for info in iter_modules(path, prefix):
|
||||
yield info
|
||||
|
||||
if ispkg:
|
||||
if info.ispkg:
|
||||
try:
|
||||
__import__(name)
|
||||
__import__(info.name)
|
||||
except ImportError:
|
||||
if onerror is not None:
|
||||
onerror(name)
|
||||
onerror(info.name)
|
||||
except Exception:
|
||||
if onerror is not None:
|
||||
onerror(name)
|
||||
onerror(info.name)
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
path = getattr(sys.modules[name], '__path__', None) or []
|
||||
path = getattr(sys.modules[info.name], '__path__', None) or []
|
||||
|
||||
# don't traverse path items we've seen before
|
||||
path = [p for p in path if not seen(p)]
|
||||
|
||||
yield from walk_packages(path, name+'.', onerror)
|
||||
yield from walk_packages(path, info.name+'.', onerror)
|
||||
|
||||
|
||||
def iter_modules(path=None, prefix=''):
|
||||
"""Yields (module_finder, name, ispkg) for all submodules on path,
|
||||
"""Yields ModuleInfo for all submodules on path,
|
||||
or, if path is None, all top-level modules on sys.path.
|
||||
|
||||
'path' should be either None or a list of paths to look for
|
||||
|
@ -111,7 +117,6 @@ def iter_modules(path=None, prefix=''):
|
|||
'prefix' is a string to output on the front of every module name
|
||||
on output.
|
||||
"""
|
||||
|
||||
if path is None:
|
||||
importers = iter_importers()
|
||||
else:
|
||||
|
@ -122,7 +127,7 @@ def iter_modules(path=None, prefix=''):
|
|||
for name, ispkg in iter_importer_modules(i, prefix):
|
||||
if name not in yielded:
|
||||
yielded[name] = 1
|
||||
yield i, name, ispkg
|
||||
yield ModuleInfo(i, name, ispkg)
|
||||
|
||||
|
||||
@simplegeneric
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue