diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2019-09-10 13:53:31 (GMT) |
---|---|---|
committer | Brett Cannon <54418+brettcannon@users.noreply.github.com> | 2019-09-10 13:53:31 (GMT) |
commit | 17499d82702432955d8e442a1871ff276ca64bc5 (patch) | |
tree | 377a62315e01cf4b38e06b713645f30910a284c7 /Lib/importlib | |
parent | 97d7906e30eeee1261b20a45a22242a8accb1cfb (diff) | |
download | cpython-17499d82702432955d8e442a1871ff276ca64bc5.zip cpython-17499d82702432955d8e442a1871ff276ca64bc5.tar.gz cpython-17499d82702432955d8e442a1871ff276ca64bc5.tar.bz2 |
bpo-38086: Sync importlib.metadata with importlib_metadata 0.21. (GH-15840)
https://gitlab.com/python-devs/importlib_metadata/-/tags/0.21
Diffstat (limited to 'Lib/importlib')
-rw-r--r-- | Lib/importlib/_bootstrap_external.py | 18 | ||||
-rw-r--r-- | Lib/importlib/metadata.py | 63 |
2 files changed, 59 insertions, 22 deletions
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 671b043..ec4bbec 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1370,21 +1370,19 @@ class PathFinder: return spec.loader @classmethod - def find_distributions(cls, name=None, path=None): + def find_distributions(self, context=None): """ Find distributions. Return an iterable of all Distribution instances capable of - loading the metadata for packages matching the ``name`` - (or all names if not supplied) along the paths in the list - of directories ``path`` (defaults to sys.path). + loading the metadata for packages matching ``context.name`` + (or all names if ``None`` indicated) along the paths in the list + of directories ``context.path``. """ - import re - from importlib.metadata import PathDistribution - if path is None: - path = sys.path - pattern = '.*' if name is None else re.escape(name) - found = cls._search_paths(pattern, path) + from importlib.metadata import PathDistribution, DistributionFinder + if context is None: + context = DistributionFinder.Context() + found = self._search_paths(context.pattern, context.path) return map(PathDistribution, found) @classmethod diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index 3b46142..e230766 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -19,6 +19,7 @@ from itertools import starmap __all__ = [ 'Distribution', + 'DistributionFinder', 'PackageNotFoundError', 'distribution', 'distributions', @@ -158,7 +159,7 @@ class Distribution: metadata cannot be found. """ for resolver in cls._discover_resolvers(): - dists = resolver(name) + dists = resolver(DistributionFinder.Context(name=name)) dist = next(dists, None) if dist is not None: return dist @@ -166,17 +167,34 @@ class Distribution: raise PackageNotFoundError(name) @classmethod - def discover(cls): + def discover(cls, **kwargs): """Return an iterable of Distribution objects for all packages. + Pass a ``context`` or pass keyword arguments for constructing + a context. + + :context: A ``DistributionFinder.Context`` object. :return: Iterable of Distribution objects for all packages. """ + context = kwargs.pop('context', None) + if context and kwargs: + raise ValueError("cannot accept context and kwargs") + context = context or DistributionFinder.Context(**kwargs) return itertools.chain.from_iterable( - resolver() + resolver(context) for resolver in cls._discover_resolvers() ) @staticmethod + def at(path): + """Return a Distribution for the indicated metadata path + + :param path: a string or path-like object + :return: a concrete Distribution instance for the path + """ + return PathDistribution(pathlib.Path(path)) + + @staticmethod def _discover_resolvers(): """Search the meta_path for resolvers.""" declared = ( @@ -215,7 +233,7 @@ class Distribution: def files(self): """Files in this distribution. - :return: Iterable of PackagePath for this distribution or None + :return: List of PackagePath for this distribution or None Result is `None` if the metadata file that enumerates files (i.e. RECORD for dist-info or SOURCES.txt for egg-info) is @@ -231,7 +249,7 @@ class Distribution: result.dist = self return result - return file_lines and starmap(make_file, csv.reader(file_lines)) + return file_lines and list(starmap(make_file, csv.reader(file_lines))) def _read_files_distinfo(self): """ @@ -251,7 +269,8 @@ class Distribution: @property def requires(self): """Generated requirements specified for this Distribution""" - return self._read_dist_info_reqs() or self._read_egg_info_reqs() + reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() + return reqs and list(reqs) def _read_dist_info_reqs(self): return self.metadata.get_all('Requires-Dist') @@ -312,15 +331,35 @@ class DistributionFinder(MetaPathFinder): A MetaPathFinder capable of discovering installed distributions. """ + class Context: + + name = None + """ + Specific name for which a distribution finder should match. + """ + + def __init__(self, **kwargs): + vars(self).update(kwargs) + + @property + def path(self): + """ + The path that a distribution finder should search. + """ + return vars(self).get('path', sys.path) + + @property + def pattern(self): + return '.*' if self.name is None else re.escape(self.name) + @abc.abstractmethod - def find_distributions(self, name=None, path=None): + def find_distributions(self, context=Context()): """ Find distributions. Return an iterable of all Distribution instances capable of - loading the metadata for packages matching the ``name`` - (or all names if not supplied) along the paths in the list - of directories ``path`` (defaults to sys.path). + loading the metadata for packages matching the ``context``, + a DistributionFinder.Context instance. """ @@ -352,12 +391,12 @@ def distribution(package): return Distribution.from_name(package) -def distributions(): +def distributions(**kwargs): """Get all ``Distribution`` instances in the current environment. :return: An iterable of ``Distribution`` instances. """ - return Distribution.discover() + return Distribution.discover(**kwargs) def metadata(package): |