Skip to content

Commit

Permalink
bpo-38121: Sync importlib.metadata with 0.22 backport (pythonGH-15993)
Browse files Browse the repository at this point in the history
* bpo-38121: Sync importlib.metadata with 0.22 backport

* πŸ“œπŸ€– Added by blurb_it.
  • Loading branch information
jaraco authored and pganssle committed Sep 12, 2019
1 parent 421a72a commit 8ed6503
Show file tree
Hide file tree
Showing 4 changed files with 991 additions and 1,097 deletions.
52 changes: 3 additions & 49 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,7 @@ def find_module(cls, fullname, path=None):
return spec.loader

@classmethod
def find_distributions(self, context=None):
def find_distributions(cls, *args, **kwargs):
"""
Find distributions.
Expand All @@ -1379,54 +1379,8 @@ def find_distributions(self, context=None):
(or all names if ``None`` indicated) along the paths in the list
of directories ``context.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
def _search_paths(cls, pattern, paths):
"""Find metadata directories in paths heuristically."""
import itertools
return itertools.chain.from_iterable(
cls._search_path(path, pattern)
for path in map(cls._switch_path, paths)
)

@staticmethod
def _switch_path(path):
from contextlib import suppress
import zipfile
import pathlib
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):
import re
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):
import re
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))
from importlib.metadata import MetadataPathFinder
return MetadataPathFinder.find_distributions(*args, **kwargs)


class FileFinder:
Expand Down
91 changes: 75 additions & 16 deletions Lib/importlib/metadata.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -363,6 +365,58 @@ def find_distributions(self, context=Context()):
"""


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.
Expand All @@ -382,13 +436,13 @@ def locate_file(self, path):
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):
Expand All @@ -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():
Expand All @@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update parameter names on functions in importlib.metadata matching the changes in the 0.22 release of importlib_metadata.
Loading

0 comments on commit 8ed6503

Please sign in to comment.