diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2016-09-08 01:37:17 (GMT) |
---|---|---|
committer | Eric Snow <ericsnowcurrently@gmail.com> | 2016-09-08 01:37:17 (GMT) |
commit | d5f92239818eef182fadc7c6f81f70912090573d (patch) | |
tree | 6ac89131eb8c69f3f2a752cbde3a6376f86f9454 /Lib | |
parent | 8e7cdb2586193726e0263eeec82c05f2a0d9c2c9 (diff) | |
download | cpython-d5f92239818eef182fadc7c6f81f70912090573d.zip cpython-d5f92239818eef182fadc7c6f81f70912090573d.tar.gz cpython-d5f92239818eef182fadc7c6f81f70912090573d.tar.bz2 |
Issue #17211: Yield a namedtuple in pkgutil.
Patch by Ramchandra Apte.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/pkgutil.py | 29 | ||||
-rw-r--r-- | Lib/test/test_pkgutil.py | 5 | ||||
-rw-r--r-- | Lib/test/test_runpy.py | 11 |
3 files changed, 26 insertions, 19 deletions
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 7fc356c..e37ad45 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -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 diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index ae2aa1b..fc04dcf 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -81,8 +81,9 @@ class PkgutilTests(unittest.TestCase): self.assertEqual(res2, RESOURCE_DATA) names = [] - for loader, name, ispkg in pkgutil.iter_modules([zip_file]): - names.append(name) + for moduleinfo in pkgutil.iter_modules([zip_file]): + self.assertIsInstance(moduleinfo, pkgutil.ModuleInfo) + names.append(moduleinfo.name) self.assertEqual(names, ['test_getdata_zipfile']) del sys.path[0] diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index db55db7..02b4d62 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -577,13 +577,14 @@ from ..uncle.cousin import nephew self.addCleanup(self._del_pkg, pkg_dir) for depth in range(2, max_depth+1): self._add_relative_modules(pkg_dir, "", depth) - for finder, mod_name, ispkg in pkgutil.walk_packages([pkg_dir]): - self.assertIsInstance(finder, + for moduleinfo in pkgutil.walk_packages([pkg_dir]): + self.assertIsInstance(moduleinfo, pkgutil.ModuleInfo) + self.assertIsInstance(moduleinfo.module_finder, importlib.machinery.FileFinder) - if ispkg: - expected_packages.remove(mod_name) + if moduleinfo.ispkg: + expected_packages.remove(moduleinfo.name) else: - expected_modules.remove(mod_name) + expected_modules.remove(moduleinfo.name) self.assertEqual(len(expected_packages), 0, expected_packages) self.assertEqual(len(expected_modules), 0, expected_modules) |