Updated importlib-metadata to 2.1.3

This commit is contained in:
Labrys of Knossos 2022-11-29 01:35:03 -05:00
parent 684cca8c9b
commit f1624a586f
17 changed files with 154 additions and 64 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals, absolute_import
import io
import os
import re
@ -5,8 +7,6 @@ import abc
import csv
import sys
import zipp
import email
import pathlib
import operator
import functools
import itertools
@ -14,18 +14,30 @@ import posixpath
import collections
from ._compat import (
NullFinder,
PyPy_repr,
install,
)
from configparser import ConfigParser
from contextlib import suppress
NullFinder,
ConfigParser,
suppress,
map,
FileNotFoundError,
IsADirectoryError,
NotADirectoryError,
PermissionError,
pathlib,
ModuleNotFoundError,
MetaPathFinder,
email_message_from_string,
PyPy_repr,
unique_ordered,
str,
)
from importlib import import_module
from importlib.abc import MetaPathFinder
from itertools import starmap
__metaclass__ = type
__all__ = [
'Distribution',
'DistributionFinder',
@ -37,7 +49,7 @@ __all__ = [
'metadata',
'requires',
'version',
]
]
class PackageNotFoundError(ModuleNotFoundError):
@ -49,13 +61,13 @@ class PackageNotFoundError(ModuleNotFoundError):
@property
def name(self):
(name,) = self.args
name, = self.args
return name
class EntryPoint(
PyPy_repr, collections.namedtuple('EntryPointBase', 'name value group')
):
PyPy_repr,
collections.namedtuple('EntryPointBase', 'name value group')):
"""An entry point as defined by Python packaging conventions.
See `the packaging docs on entry points
@ -65,9 +77,9 @@ class EntryPoint(
pattern = re.compile(
r'(?P<module>[\w.]+)\s*'
r'(:\s*(?P<attr>[\w.]+))?\s*'
r'(?P<extras>\[.*\])?\s*$'
)
r'(:\s*(?P<attr>[\w.]+)\s*)?'
r'((?P<extras>\[.*\])\s*)?$'
)
"""
A regular expression describing the syntax for an entry point,
which might look like:
@ -115,7 +127,7 @@ class EntryPoint(
cls(name, value, group)
for group in config.sections()
for name, value in config.items(group)
]
]
@classmethod
def _from_text(cls, text):
@ -139,7 +151,7 @@ class EntryPoint(
return (
self.__class__,
(self.name, self.value, self.group),
)
)
class PackagePath(pathlib.PurePosixPath):
@ -217,8 +229,9 @@ class Distribution:
raise ValueError("cannot accept context and kwargs")
context = context or DistributionFinder.Context(**kwargs)
return itertools.chain.from_iterable(
resolver(context) for resolver in cls._discover_resolvers()
)
resolver(context)
for resolver in cls._discover_resolvers()
)
@staticmethod
def at(path):
@ -233,20 +246,20 @@ class Distribution:
def _discover_resolvers():
"""Search the meta_path for resolvers."""
declared = (
getattr(finder, 'find_distributions', None) for finder in sys.meta_path
)
getattr(finder, 'find_distributions', None)
for finder in sys.meta_path
)
return filter(None, declared)
@classmethod
def _local(cls, root='.'):
from pep517 import build, meta
system = build.compat_system(root)
builder = functools.partial(
meta.build,
source_dir=root,
system=system,
)
)
return PathDistribution(zipp.Path(meta.build_as_zip(builder)))
@property
@ -263,8 +276,8 @@ class Distribution:
# effect is to just end up using the PathDistribution's self._path
# (which points to the egg-info file) attribute unchanged.
or self.read_text('')
)
return email.message_from_string(text)
)
return email_message_from_string(text)
@property
def version(self):
@ -330,10 +343,9 @@ class Distribution:
section_pairs = cls._read_sections(source.splitlines())
sections = {
section: list(map(operator.itemgetter('line'), results))
for section, results in itertools.groupby(
section_pairs, operator.itemgetter('section')
)
}
for section, results in
itertools.groupby(section_pairs, operator.itemgetter('section'))
}
return cls._convert_egg_info_reqs_to_simple_reqs(sections)
@staticmethod
@ -357,7 +369,6 @@ class Distribution:
requirement. This method converts the former to the
latter. See _test_deps_from_requires_text for an example.
"""
def make_condition(name):
return name and 'extra == "{name}"'.format(name=name)
@ -436,7 +447,7 @@ class FastPath:
def children(self):
with suppress(Exception):
return os.listdir(self.root or '')
return os.listdir(self.root or '.')
with suppress(Exception):
return self.zip_children()
return []
@ -446,21 +457,23 @@ class FastPath:
names = zip_path.root.namelist()
self.joinpath = zip_path.joinpath
return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names)
return unique_ordered(
child.split(posixpath.sep, 1)[0]
for child in names
)
def search(self, name):
return (
self.joinpath(child)
for child in self.children()
if name.matches(child, self.base)
)
)
class Prepared:
"""
A prepared search for metadata on a possibly-named package.
"""
normalized = None
suffixes = '.dist-info', '.egg-info'
exact_matches = [''][:0]
@ -470,7 +483,8 @@ class Prepared:
if name is None:
return
self.normalized = self.normalize(name)
self.exact_matches = [self.normalized + suffix for suffix in self.suffixes]
self.exact_matches = [
self.normalized + suffix for suffix in self.suffixes]
@staticmethod
def normalize(name):
@ -493,12 +507,13 @@ class Prepared:
name, sep, rest = pre.partition('-')
return (
low in self.exact_matches
or ext in self.suffixes
and (not self.normalized or name.replace('.', '_') == self.normalized)
or ext in self.suffixes and (
not self.normalized or
name.replace('.', '_') == self.normalized
)
# legacy case:
or self.is_egg(base)
and low == 'egg-info'
)
or self.is_egg(base) and low == 'egg-info'
)
def is_egg(self, base):
normalized = self.legacy_normalize(self.name or '')
@ -507,8 +522,7 @@ class Prepared:
return (
base == versionless_egg_name
or base.startswith(prefix)
and base.endswith('.egg')
)
and base.endswith('.egg'))
@install
@ -535,8 +549,9 @@ class MetadataPathFinder(NullFinder, DistributionFinder):
def _search_paths(cls, name, paths):
"""Find metadata directories in paths heuristically."""
return itertools.chain.from_iterable(
path.search(Prepared(name)) for path in map(FastPath, paths)
)
path.search(Prepared(name))
for path in map(FastPath, paths)
)
class PathDistribution(Distribution):
@ -549,15 +564,9 @@ class PathDistribution(Distribution):
self._path = path
def read_text(self, filename):
with suppress(
FileNotFoundError,
IsADirectoryError,
KeyError,
NotADirectoryError,
PermissionError,
):
with suppress(FileNotFoundError, IsADirectoryError, KeyError,
NotADirectoryError, PermissionError):
return self._path.joinpath(filename).read_text(encoding='utf-8')
read_text.__doc__ = Distribution.read_text.__doc__
def locate_file(self, path):
@ -605,11 +614,15 @@ def entry_points():
:return: EntryPoint objects for all installed packages.
"""
eps = itertools.chain.from_iterable(dist.entry_points for dist in distributions())
eps = itertools.chain.from_iterable(
dist.entry_points for dist in distributions())
by_group = operator.attrgetter('group')
ordered = sorted(eps, key=by_group)
grouped = itertools.groupby(ordered, by_group)
return {group: tuple(eps) for group, eps in grouped}
return {
group: tuple(eps)
for group, eps in grouped
}
def files(distribution_name):

View file

@ -1,7 +1,59 @@
from __future__ import absolute_import, unicode_literals
import io
import abc
import sys
import email
__all__ = ['install', 'NullFinder', 'PyPy_repr']
if sys.version_info > (3,): # pragma: nocover
import builtins
from configparser import ConfigParser
import contextlib
FileNotFoundError = builtins.FileNotFoundError
IsADirectoryError = builtins.IsADirectoryError
NotADirectoryError = builtins.NotADirectoryError
PermissionError = builtins.PermissionError
map = builtins.map
from itertools import filterfalse
else: # pragma: nocover
from backports.configparser import ConfigParser
from itertools import imap as map # type: ignore
from itertools import ifilterfalse as filterfalse
import contextlib2 as contextlib
FileNotFoundError = IOError, OSError
IsADirectoryError = IOError, OSError
NotADirectoryError = IOError, OSError
PermissionError = IOError, OSError
str = type('')
suppress = contextlib.suppress
if sys.version_info > (3, 5): # pragma: nocover
import pathlib
else: # pragma: nocover
import pathlib2 as pathlib
try:
ModuleNotFoundError = builtins.FileNotFoundError
except (NameError, AttributeError): # pragma: nocover
ModuleNotFoundError = ImportError # type: ignore
if sys.version_info >= (3,): # pragma: nocover
from importlib.abc import MetaPathFinder
else: # pragma: nocover
class MetaPathFinder(object):
__metaclass__ = abc.ABCMeta
__metaclass__ = type
__all__ = [
'install', 'NullFinder', 'MetaPathFinder', 'ModuleNotFoundError',
'pathlib', 'ConfigParser', 'map', 'suppress', 'FileNotFoundError',
'NotADirectoryError', 'email_message_from_string',
]
def install(cls):
@ -25,12 +77,11 @@ def disable_stdlib_finder():
See #91 for more background for rationale on this sketchy
behavior.
"""
def matches(finder):
return getattr(
finder, '__module__', None
) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions')
return (
getattr(finder, '__module__', None) == '_frozen_importlib_external'
and hasattr(finder, 'find_distributions')
)
for finder in filter(matches, sys.meta_path): # pragma: nocover
del finder.find_distributions
@ -40,7 +91,6 @@ class NullFinder:
A "Finder" (aka "MetaClassFinder") that never finds any modules,
but may find distributions.
"""
@staticmethod
def find_spec(*args, **kwargs):
return None
@ -54,22 +104,49 @@ class NullFinder:
find_module = find_spec
def py2_message_from_string(text): # nocoverpy3
# Work around https://bugs.python.org/issue25545 where
# email.message_from_string cannot handle Unicode on Python 2.
io_buffer = io.StringIO(text)
return email.message_from_file(io_buffer)
email_message_from_string = (
py2_message_from_string
if sys.version_info < (3,) else
email.message_from_string
)
class PyPy_repr:
"""
Override repr for EntryPoint objects on PyPy to avoid __iter__ access.
Ref #97, #102.
"""
affected = hasattr(sys, 'pypy_version_info')
def __compat_repr__(self): # pragma: nocover
def make_param(name):
value = getattr(self, name)
return '{name}={value!r}'.format(**locals())
params = ', '.join(map(make_param, self._fields))
return 'EntryPoint({params})'.format(**locals())
if affected: # pragma: nocover
__repr__ = __compat_repr__
del affected
# from itertools recipes
def unique_everseen(iterable): # pragma: nocover
"List unique elements, preserving order. Remember all elements ever seen."
seen = set()
seen_add = seen.add
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
unique_ordered = (
unique_everseen if sys.version_info < (3, 7) else dict.fromkeys)