diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2019-09-12 09:29:11 (GMT) |
---|---|---|
committer | Paul Ganssle <paul@ganssle.io> | 2019-09-12 09:29:11 (GMT) |
commit | 8ed6503eca4e3ea4949479d8d7fd9ffd54f81038 (patch) | |
tree | 788674608843a63a45a376d5916bfe09a63c54a0 /Lib/importlib/metadata.py | |
parent | 421a72af4deaec96a49a79951b9c2546a2faa13d (diff) | |
download | cpython-8ed6503eca4e3ea4949479d8d7fd9ffd54f81038.zip cpython-8ed6503eca4e3ea4949479d8d7fd9ffd54f81038.tar.gz cpython-8ed6503eca4e3ea4949479d8d7fd9ffd54f81038.tar.bz2 |
bpo-38121: Sync importlib.metadata with 0.22 backport (GH-15993)
* bpo-38121: Sync importlib.metadata with 0.22 backport
* 📜🤖 Added by blurb_it.
Diffstat (limited to 'Lib/importlib/metadata.py')
-rw-r--r-- | Lib/importlib/metadata.py | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index e230766..8cb45ec 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -1,10 +1,12 @@ import io +import os import re import abc import csv import sys import email import pathlib +import zipfile import operator import functools import itertools @@ -363,6 +365,58 @@ class DistributionFinder(MetaPathFinder): """ +class MetadataPathFinder(DistributionFinder): + @classmethod + def find_distributions(cls, context=DistributionFinder.Context()): + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching ``context.name`` + (or all names if ``None`` indicated) along the paths in the list + of directories ``context.path``. + """ + found = cls._search_paths(context.pattern, context.path) + return map(PathDistribution, found) + + @classmethod + def _search_paths(cls, pattern, paths): + """Find metadata directories in paths heuristically.""" + return itertools.chain.from_iterable( + cls._search_path(path, pattern) + for path in map(cls._switch_path, paths) + ) + + @staticmethod + def _switch_path(path): + PYPY_OPEN_BUG = False + if not PYPY_OPEN_BUG or os.path.isfile(path): # pragma: no branch + with suppress(Exception): + return zipfile.Path(path) + return pathlib.Path(path) + + @classmethod + def _matches_info(cls, normalized, item): + template = r'{pattern}(-.*)?\.(dist|egg)-info' + manifest = template.format(pattern=normalized) + return re.match(manifest, item.name, flags=re.IGNORECASE) + + @classmethod + def _matches_legacy(cls, normalized, item): + template = r'{pattern}-.*\.egg[\\/]EGG-INFO' + manifest = template.format(pattern=normalized) + return re.search(manifest, str(item), flags=re.IGNORECASE) + + @classmethod + def _search_path(cls, root, pattern): + if not root.is_dir(): + return () + normalized = pattern.replace('-', '_') + return (item for item in root.iterdir() + if cls._matches_info(normalized, item) + or cls._matches_legacy(normalized, item)) + + class PathDistribution(Distribution): def __init__(self, path): """Construct a distribution from a path to the metadata directory. @@ -382,13 +436,13 @@ class PathDistribution(Distribution): return self._path.parent / path -def distribution(package): - """Get the ``Distribution`` instance for the given package. +def distribution(distribution_name): + """Get the ``Distribution`` instance for the named package. - :param package: The name of the package as a string. + :param distribution_name: The name of the distribution package as a string. :return: A ``Distribution`` instance (or subclass thereof). """ - return Distribution.from_name(package) + return Distribution.from_name(distribution_name) def distributions(**kwargs): @@ -399,23 +453,23 @@ def distributions(**kwargs): return Distribution.discover(**kwargs) -def metadata(package): - """Get the metadata for the package. +def metadata(distribution_name): + """Get the metadata for the named package. - :param package: The name of the distribution package to query. + :param distribution_name: The name of the distribution package to query. :return: An email.Message containing the parsed metadata. """ - return Distribution.from_name(package).metadata + return Distribution.from_name(distribution_name).metadata -def version(package): +def version(distribution_name): """Get the version string for the named package. - :param package: The name of the distribution package to query. + :param distribution_name: The name of the distribution package to query. :return: The version string for the package as defined in the package's "Version" metadata key. """ - return distribution(package).version + return distribution(distribution_name).version def entry_points(): @@ -434,15 +488,20 @@ def entry_points(): } -def files(package): - return distribution(package).files +def files(distribution_name): + """Return a list of files for the named package. + + :param distribution_name: The name of the distribution package to query. + :return: List of files composing the distribution. + """ + return distribution(distribution_name).files -def requires(package): +def requires(distribution_name): """ - Return a list of requirements for the indicated distribution. + Return a list of requirements for the named package. :return: An iterator of requirements, suitable for packaging.requirement.Requirement. """ - return distribution(package).requires + return distribution(distribution_name).requires |