summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2019-09-10 13:53:31 (GMT)
committerBrett Cannon <54418+brettcannon@users.noreply.github.com>2019-09-10 13:53:31 (GMT)
commit17499d82702432955d8e442a1871ff276ca64bc5 (patch)
tree377a62315e01cf4b38e06b713645f30910a284c7 /Lib/importlib
parent97d7906e30eeee1261b20a45a22242a8accb1cfb (diff)
downloadcpython-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.py18
-rw-r--r--Lib/importlib/metadata.py63
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):