login page
This commit is contained in:
13
Lib/site-packages/pipenv/vendor/importlib_metadata/LICENSE
vendored
Normal file
13
Lib/site-packages/pipenv/vendor/importlib_metadata/LICENSE
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2017-2019 Jason R. Coombs, Barry Warsaw
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
602
Lib/site-packages/pipenv/vendor/importlib_metadata/__init__.py
vendored
Normal file
602
Lib/site-packages/pipenv/vendor/importlib_metadata/__init__.py
vendored
Normal file
@@ -0,0 +1,602 @@
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import abc
|
||||
import csv
|
||||
import sys
|
||||
import zipp
|
||||
import operator
|
||||
import functools
|
||||
import itertools
|
||||
import posixpath
|
||||
import collections
|
||||
|
||||
from ._compat import (
|
||||
install,
|
||||
NullFinder,
|
||||
ConfigParser,
|
||||
suppress,
|
||||
map,
|
||||
FileNotFoundError,
|
||||
IsADirectoryError,
|
||||
NotADirectoryError,
|
||||
PermissionError,
|
||||
pathlib,
|
||||
ModuleNotFoundError,
|
||||
MetaPathFinder,
|
||||
email_message_from_string,
|
||||
PyPy_repr,
|
||||
unique_ordered,
|
||||
)
|
||||
from importlib import import_module
|
||||
from itertools import starmap
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
__all__ = [
|
||||
'Distribution',
|
||||
'DistributionFinder',
|
||||
'PackageNotFoundError',
|
||||
'distribution',
|
||||
'distributions',
|
||||
'entry_points',
|
||||
'files',
|
||||
'metadata',
|
||||
'requires',
|
||||
'version',
|
||||
]
|
||||
|
||||
|
||||
class PackageNotFoundError(ModuleNotFoundError):
|
||||
"""The package was not found."""
|
||||
|
||||
|
||||
class EntryPoint(
|
||||
PyPy_repr,
|
||||
collections.namedtuple('EntryPointBase', 'name value group')):
|
||||
"""An entry point as defined by Python packaging conventions.
|
||||
|
||||
See `the packaging docs on entry points
|
||||
<https://packaging.python.org/specifications/entry-points/>`_
|
||||
for more information.
|
||||
"""
|
||||
|
||||
pattern = re.compile(
|
||||
r'(?P<module>[\w.]+)\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:
|
||||
|
||||
- module
|
||||
- package.module
|
||||
- package.module:attribute
|
||||
- package.module:object.attribute
|
||||
- package.module:attr [extra1, extra2]
|
||||
|
||||
Other combinations are possible as well.
|
||||
|
||||
The expression is lenient about whitespace around the ':',
|
||||
following the attr, and following any extras.
|
||||
"""
|
||||
|
||||
def load(self):
|
||||
"""Load the entry point from its definition. If only a module
|
||||
is indicated by the value, return that module. Otherwise,
|
||||
return the named object.
|
||||
"""
|
||||
match = self.pattern.match(self.value)
|
||||
module = import_module(match.group('module'))
|
||||
attrs = filter(None, (match.group('attr') or '').split('.'))
|
||||
return functools.reduce(getattr, attrs, module)
|
||||
|
||||
@property
|
||||
def module(self):
|
||||
match = self.pattern.match(self.value)
|
||||
return match.group('module')
|
||||
|
||||
@property
|
||||
def attr(self):
|
||||
match = self.pattern.match(self.value)
|
||||
return match.group('attr')
|
||||
|
||||
@property
|
||||
def extras(self):
|
||||
match = self.pattern.match(self.value)
|
||||
return list(re.finditer(r'\w+', match.group('extras') or ''))
|
||||
|
||||
@classmethod
|
||||
def _from_config(cls, config):
|
||||
return [
|
||||
cls(name, value, group)
|
||||
for group in config.sections()
|
||||
for name, value in config.items(group)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _from_text(cls, text):
|
||||
config = ConfigParser(delimiters='=')
|
||||
# case sensitive: https://stackoverflow.com/q/1611799/812183
|
||||
config.optionxform = str
|
||||
try:
|
||||
config.read_string(text)
|
||||
except AttributeError: # pragma: nocover
|
||||
# Python 2 has no read_string
|
||||
config.readfp(io.StringIO(text))
|
||||
return EntryPoint._from_config(config)
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Supply iter so one may construct dicts of EntryPoints easily.
|
||||
"""
|
||||
return iter((self.name, self))
|
||||
|
||||
def __reduce__(self):
|
||||
return (
|
||||
self.__class__,
|
||||
(self.name, self.value, self.group),
|
||||
)
|
||||
|
||||
|
||||
class PackagePath(pathlib.PurePosixPath):
|
||||
"""A reference to a path in a package"""
|
||||
|
||||
def read_text(self, encoding='utf-8'):
|
||||
with self.locate().open(encoding=encoding) as stream:
|
||||
return stream.read()
|
||||
|
||||
def read_binary(self):
|
||||
with self.locate().open('rb') as stream:
|
||||
return stream.read()
|
||||
|
||||
def locate(self):
|
||||
"""Return a path-like object for this path"""
|
||||
return self.dist.locate_file(self)
|
||||
|
||||
|
||||
class FileHash:
|
||||
def __init__(self, spec):
|
||||
self.mode, _, self.value = spec.partition('=')
|
||||
|
||||
def __repr__(self):
|
||||
return '<FileHash mode: {} value: {}>'.format(self.mode, self.value)
|
||||
|
||||
|
||||
class Distribution:
|
||||
"""A Python distribution package."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def read_text(self, filename):
|
||||
"""Attempt to load metadata file given by the name.
|
||||
|
||||
:param filename: The name of the file in the distribution info.
|
||||
:return: The text if found, otherwise None.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def locate_file(self, path):
|
||||
"""
|
||||
Given a path to a file in this distribution, return a path
|
||||
to it.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, name):
|
||||
"""Return the Distribution for the given package name.
|
||||
|
||||
:param name: The name of the distribution package to search for.
|
||||
:return: The Distribution instance (or subclass thereof) for the named
|
||||
package, if found.
|
||||
:raises PackageNotFoundError: When the named package's distribution
|
||||
metadata cannot be found.
|
||||
"""
|
||||
for resolver in cls._discover_resolvers():
|
||||
dists = resolver(DistributionFinder.Context(name=name))
|
||||
dist = next(dists, None)
|
||||
if dist is not None:
|
||||
return dist
|
||||
else:
|
||||
raise PackageNotFoundError(name)
|
||||
|
||||
@classmethod
|
||||
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(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 = (
|
||||
getattr(finder, 'find_distributions', None)
|
||||
for finder in sys.meta_path
|
||||
)
|
||||
return filter(None, declared)
|
||||
|
||||
@property
|
||||
def metadata(self):
|
||||
"""Return the parsed metadata for this Distribution.
|
||||
|
||||
The returned object will have keys that name the various bits of
|
||||
metadata. See PEP 566 for details.
|
||||
"""
|
||||
text = (
|
||||
self.read_text('METADATA')
|
||||
or self.read_text('PKG-INFO')
|
||||
# This last clause is here to support old egg-info files. Its
|
||||
# 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)
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
"""Return the 'Version' metadata for the distribution package."""
|
||||
return self.metadata['Version']
|
||||
|
||||
@property
|
||||
def entry_points(self):
|
||||
return EntryPoint._from_text(self.read_text('entry_points.txt'))
|
||||
|
||||
@property
|
||||
def files(self):
|
||||
"""Files in this distribution.
|
||||
|
||||
: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
|
||||
missing.
|
||||
Result may be empty if the metadata exists but is empty.
|
||||
"""
|
||||
file_lines = self._read_files_distinfo() or self._read_files_egginfo()
|
||||
|
||||
def make_file(name, hash=None, size_str=None):
|
||||
result = PackagePath(name)
|
||||
result.hash = FileHash(hash) if hash else None
|
||||
result.size = int(size_str) if size_str else None
|
||||
result.dist = self
|
||||
return result
|
||||
|
||||
return file_lines and list(starmap(make_file, csv.reader(file_lines)))
|
||||
|
||||
def _read_files_distinfo(self):
|
||||
"""
|
||||
Read the lines of RECORD
|
||||
"""
|
||||
text = self.read_text('RECORD')
|
||||
return text and text.splitlines()
|
||||
|
||||
def _read_files_egginfo(self):
|
||||
"""
|
||||
SOURCES.txt might contain literal commas, so wrap each line
|
||||
in quotes.
|
||||
"""
|
||||
text = self.read_text('SOURCES.txt')
|
||||
return text and map('"{}"'.format, text.splitlines())
|
||||
|
||||
@property
|
||||
def requires(self):
|
||||
"""Generated requirements specified for this Distribution"""
|
||||
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')
|
||||
|
||||
def _read_egg_info_reqs(self):
|
||||
source = self.read_text('requires.txt')
|
||||
return source and self._deps_from_requires_text(source)
|
||||
|
||||
@classmethod
|
||||
def _deps_from_requires_text(cls, source):
|
||||
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'))
|
||||
}
|
||||
return cls._convert_egg_info_reqs_to_simple_reqs(sections)
|
||||
|
||||
@staticmethod
|
||||
def _read_sections(lines):
|
||||
section = None
|
||||
for line in filter(None, lines):
|
||||
section_match = re.match(r'\[(.*)\]$', line)
|
||||
if section_match:
|
||||
section = section_match.group(1)
|
||||
continue
|
||||
yield locals()
|
||||
|
||||
@staticmethod
|
||||
def _convert_egg_info_reqs_to_simple_reqs(sections):
|
||||
"""
|
||||
Historically, setuptools would solicit and store 'extra'
|
||||
requirements, including those with environment markers,
|
||||
in separate sections. More modern tools expect each
|
||||
dependency to be defined separately, with any relevant
|
||||
extras and environment markers attached directly to that
|
||||
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)
|
||||
|
||||
def parse_condition(section):
|
||||
section = section or ''
|
||||
extra, sep, markers = section.partition(':')
|
||||
if extra and markers:
|
||||
markers = '({markers})'.format(markers=markers)
|
||||
conditions = list(filter(None, [markers, make_condition(extra)]))
|
||||
return '; ' + ' and '.join(conditions) if conditions else ''
|
||||
|
||||
for section, deps in sections.items():
|
||||
for dep in deps:
|
||||
yield dep + parse_condition(section)
|
||||
|
||||
|
||||
class DistributionFinder(MetaPathFinder):
|
||||
"""
|
||||
A MetaPathFinder capable of discovering installed distributions.
|
||||
"""
|
||||
|
||||
class Context:
|
||||
"""
|
||||
Keyword arguments presented by the caller to
|
||||
``distributions()`` or ``Distribution.discover()``
|
||||
to narrow the scope of a search for distributions
|
||||
in all DistributionFinders.
|
||||
|
||||
Each DistributionFinder may expect any parameters
|
||||
and should attempt to honor the canonical
|
||||
parameters defined below when appropriate.
|
||||
"""
|
||||
|
||||
name = None
|
||||
"""
|
||||
Specific name for which a distribution finder should match.
|
||||
A name of ``None`` matches all distributions.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
vars(self).update(kwargs)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""
|
||||
The path that a distribution finder should search.
|
||||
|
||||
Typically refers to Python package paths and defaults
|
||||
to ``sys.path``.
|
||||
"""
|
||||
return vars(self).get('path', sys.path)
|
||||
|
||||
@abc.abstractmethod
|
||||
def find_distributions(self, context=Context()):
|
||||
"""
|
||||
Find distributions.
|
||||
|
||||
Return an iterable of all Distribution instances capable of
|
||||
loading the metadata for packages matching the ``context``,
|
||||
a DistributionFinder.Context instance.
|
||||
"""
|
||||
|
||||
|
||||
class FastPath:
|
||||
"""
|
||||
Micro-optimized class for searching a path for
|
||||
children.
|
||||
"""
|
||||
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.base = os.path.basename(root).lower()
|
||||
|
||||
def joinpath(self, child):
|
||||
return pathlib.Path(self.root, child)
|
||||
|
||||
def children(self):
|
||||
with suppress(Exception):
|
||||
return os.listdir(self.root or '')
|
||||
with suppress(Exception):
|
||||
return self.zip_children()
|
||||
return []
|
||||
|
||||
def zip_children(self):
|
||||
zip_path = zipp.Path(self.root)
|
||||
names = zip_path.root.namelist()
|
||||
self.joinpath = zip_path.joinpath
|
||||
|
||||
return unique_ordered(
|
||||
child.split(posixpath.sep, 1)[0]
|
||||
for child in names
|
||||
)
|
||||
|
||||
def is_egg(self, search):
|
||||
base = self.base
|
||||
return (
|
||||
base == search.versionless_egg_name
|
||||
or base.startswith(search.prefix)
|
||||
and base.endswith('.egg'))
|
||||
|
||||
def search(self, name):
|
||||
for child in self.children():
|
||||
n_low = child.lower()
|
||||
if (n_low in name.exact_matches
|
||||
or n_low.startswith(name.prefix)
|
||||
and n_low.endswith(name.suffixes)
|
||||
# legacy case:
|
||||
or self.is_egg(name) and n_low == 'egg-info'):
|
||||
yield self.joinpath(child)
|
||||
|
||||
|
||||
class Prepared:
|
||||
"""
|
||||
A prepared search for metadata on a possibly-named package.
|
||||
"""
|
||||
normalized = ''
|
||||
prefix = ''
|
||||
suffixes = '.dist-info', '.egg-info'
|
||||
exact_matches = [''][:0]
|
||||
versionless_egg_name = ''
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
if name is None:
|
||||
return
|
||||
self.normalized = name.lower().replace('-', '_')
|
||||
self.prefix = self.normalized + '-'
|
||||
self.exact_matches = [
|
||||
self.normalized + suffix for suffix in self.suffixes]
|
||||
self.versionless_egg_name = self.normalized + '.egg'
|
||||
|
||||
|
||||
@install
|
||||
class MetadataPathFinder(NullFinder, DistributionFinder):
|
||||
"""A degenerate finder for distribution packages on the file system.
|
||||
|
||||
This finder supplies only a find_distributions() method for versions
|
||||
of Python that do not have a PathFinder find_distributions().
|
||||
"""
|
||||
|
||||
def find_distributions(self, 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 = self._search_paths(context.name, context.path)
|
||||
return map(PathDistribution, found)
|
||||
|
||||
@classmethod
|
||||
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)
|
||||
)
|
||||
|
||||
|
||||
class PathDistribution(Distribution):
|
||||
def __init__(self, path):
|
||||
"""Construct a distribution from a path to the metadata directory.
|
||||
|
||||
:param path: A pathlib.Path or similar object supporting
|
||||
.joinpath(), __div__, .parent, and .read_text().
|
||||
"""
|
||||
self._path = path
|
||||
|
||||
def read_text(self, filename):
|
||||
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):
|
||||
return self._path.parent / path
|
||||
|
||||
|
||||
def distribution(distribution_name):
|
||||
"""Get the ``Distribution`` instance for the named package.
|
||||
|
||||
:param distribution_name: The name of the distribution package as a string.
|
||||
:return: A ``Distribution`` instance (or subclass thereof).
|
||||
"""
|
||||
return Distribution.from_name(distribution_name)
|
||||
|
||||
|
||||
def distributions(**kwargs):
|
||||
"""Get all ``Distribution`` instances in the current environment.
|
||||
|
||||
:return: An iterable of ``Distribution`` instances.
|
||||
"""
|
||||
return Distribution.discover(**kwargs)
|
||||
|
||||
|
||||
def metadata(distribution_name):
|
||||
"""Get the metadata for the named package.
|
||||
|
||||
:param distribution_name: The name of the distribution package to query.
|
||||
:return: An email.Message containing the parsed metadata.
|
||||
"""
|
||||
return Distribution.from_name(distribution_name).metadata
|
||||
|
||||
|
||||
def version(distribution_name):
|
||||
"""Get the version string for the named package.
|
||||
|
||||
: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(distribution_name).version
|
||||
|
||||
|
||||
def entry_points():
|
||||
"""Return EntryPoint objects for all installed packages.
|
||||
|
||||
:return: EntryPoint objects for all installed packages.
|
||||
"""
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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(distribution_name):
|
||||
"""
|
||||
Return a list of requirements for the named package.
|
||||
|
||||
:return: An iterator of requirements, suitable for
|
||||
packaging.requirement.Requirement.
|
||||
"""
|
||||
return distribution(distribution_name).requires
|
||||
|
||||
|
||||
__version__ = version(__name__)
|
||||
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/__pycache__/_compat.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/__pycache__/_compat.cpython-38.pyc
vendored
Normal file
Binary file not shown.
150
Lib/site-packages/pipenv/vendor/importlib_metadata/_compat.py
vendored
Normal file
150
Lib/site-packages/pipenv/vendor/importlib_metadata/_compat.py
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import io
|
||||
import abc
|
||||
import sys
|
||||
import email
|
||||
|
||||
|
||||
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
|
||||
|
||||
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):
|
||||
"""
|
||||
Class decorator for installation on sys.meta_path.
|
||||
|
||||
Adds the backport DistributionFinder to sys.meta_path and
|
||||
attempts to disable the finder functionality of the stdlib
|
||||
DistributionFinder.
|
||||
"""
|
||||
sys.meta_path.append(cls())
|
||||
disable_stdlib_finder()
|
||||
return cls
|
||||
|
||||
|
||||
def disable_stdlib_finder():
|
||||
"""
|
||||
Give the backport primacy for discovering path-based distributions
|
||||
by monkey-patching the stdlib O_O.
|
||||
|
||||
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')
|
||||
)
|
||||
for finder in filter(matches, sys.meta_path): # pragma: nocover
|
||||
del finder.find_distributions
|
||||
|
||||
|
||||
class NullFinder:
|
||||
"""
|
||||
A "Finder" (aka "MetaClassFinder") that never finds any modules,
|
||||
but may find distributions.
|
||||
"""
|
||||
@staticmethod
|
||||
def find_spec(*args, **kwargs):
|
||||
return None
|
||||
|
||||
# In Python 2, the import system requires finders
|
||||
# to have a find_module() method, but this usage
|
||||
# is deprecated in Python 3 in favor of find_spec().
|
||||
# For the purposes of this finder (i.e. being present
|
||||
# on sys.meta_path but having no other import
|
||||
# system functionality), the two methods are identical.
|
||||
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)
|
||||
0
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__init__.py
vendored
Normal file
0
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__init__.py
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__pycache__/conf.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/__pycache__/conf.cpython-38.pyc
vendored
Normal file
Binary file not shown.
275
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/changelog.rst
vendored
Normal file
275
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/changelog.rst
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
=========================
|
||||
importlib_metadata NEWS
|
||||
=========================
|
||||
|
||||
v1.6.0
|
||||
======
|
||||
|
||||
* Added ``module`` and ``attr`` attributes to ``EntryPoint``
|
||||
|
||||
v1.5.2
|
||||
======
|
||||
|
||||
* Fix redundant entries from ``FastPath.zip_children``.
|
||||
Closes #117.
|
||||
|
||||
v1.5.1
|
||||
======
|
||||
|
||||
* Improve reliability and consistency of compatibility
|
||||
imports for contextlib and pathlib when running tests.
|
||||
Closes #116.
|
||||
|
||||
v1.5.0
|
||||
======
|
||||
|
||||
* Additional performance optimizations in FastPath now
|
||||
saves an additional 20% on a typical call.
|
||||
* Correct for issue where PyOxidizer finder has no
|
||||
``__module__`` attribute. Closes #110.
|
||||
|
||||
v1.4.0
|
||||
======
|
||||
|
||||
* Through careful optimization, ``distribution()`` is
|
||||
3-4x faster. Thanks to Antony Lee for the
|
||||
contribution. Closes #95.
|
||||
|
||||
* When searching through ``sys.path``, if any error
|
||||
occurs attempting to list a path entry, that entry
|
||||
is skipped, making the system much more lenient
|
||||
to errors. Closes #94.
|
||||
|
||||
v1.3.0
|
||||
======
|
||||
|
||||
* Improve custom finders documentation. Closes #105.
|
||||
|
||||
v1.2.0
|
||||
======
|
||||
|
||||
* Once again, drop support for Python 3.4. Ref #104.
|
||||
|
||||
v1.1.3
|
||||
======
|
||||
|
||||
* Restored support for Python 3.4 due to improper version
|
||||
compatibility declarations in the v1.1.0 and v1.1.1
|
||||
releases. Closes #104.
|
||||
|
||||
v1.1.2
|
||||
======
|
||||
|
||||
* Repaired project metadata to correctly declare the
|
||||
``python_requires`` directive. Closes #103.
|
||||
|
||||
v1.1.1
|
||||
======
|
||||
|
||||
* Fixed ``repr(EntryPoint)`` on PyPy 3 also. Closes #102.
|
||||
|
||||
v1.1.0
|
||||
======
|
||||
|
||||
* Dropped support for Python 3.4.
|
||||
* EntryPoints are now pickleable. Closes #96.
|
||||
* Fixed ``repr(EntryPoint)`` on PyPy 2. Closes #97.
|
||||
|
||||
v1.0.0
|
||||
======
|
||||
|
||||
* Project adopts semver for versioning.
|
||||
|
||||
* Removed compatibility shim introduced in 0.23.
|
||||
|
||||
* For better compatibility with the stdlib implementation and to
|
||||
avoid the same distributions being discovered by the stdlib and
|
||||
backport implementations, the backport now disables the
|
||||
stdlib DistributionFinder during initialization (import time).
|
||||
Closes #91 and closes #100.
|
||||
|
||||
0.23
|
||||
====
|
||||
* Added a compatibility shim to prevent failures on beta releases
|
||||
of Python before the signature changed to accept the
|
||||
"context" parameter on find_distributions. This workaround
|
||||
will have a limited lifespan, not to extend beyond release of
|
||||
Python 3.8 final.
|
||||
|
||||
0.22
|
||||
====
|
||||
* Renamed ``package`` parameter to ``distribution_name``
|
||||
as `recommended <https://bugs.python.org/issue34632#msg349423>`_
|
||||
in the following functions: ``distribution``, ``metadata``,
|
||||
``version``, ``files``, and ``requires``. This
|
||||
backward-incompatible change is expected to have little impact
|
||||
as these functions are assumed to be primarily used with
|
||||
positional parameters.
|
||||
|
||||
0.21
|
||||
====
|
||||
* ``importlib.metadata`` now exposes the ``DistributionFinder``
|
||||
metaclass and references it in the docs for extending the
|
||||
search algorithm.
|
||||
* Add ``Distribution.at`` for constructing a Distribution object
|
||||
from a known metadata directory on the file system. Closes #80.
|
||||
* Distribution finders now receive a context object that
|
||||
supplies ``.path`` and ``.name`` properties. This change
|
||||
introduces a fundamental backward incompatibility for
|
||||
any projects implementing a ``find_distributions`` method
|
||||
on a ``MetaPathFinder``. This new layer of abstraction
|
||||
allows this context to be supplied directly or constructed
|
||||
on demand and opens the opportunity for a
|
||||
``find_distributions`` method to solicit additional
|
||||
context from the caller. Closes #85.
|
||||
|
||||
0.20
|
||||
====
|
||||
* Clarify in the docs that calls to ``.files`` could return
|
||||
``None`` when the metadata is not present. Closes #69.
|
||||
* Return all requirements and not just the first for dist-info
|
||||
packages. Closes #67.
|
||||
|
||||
0.19
|
||||
====
|
||||
* Restrain over-eager egg metadata resolution.
|
||||
* Add support for entry points with colons in the name. Closes #75.
|
||||
|
||||
0.18
|
||||
====
|
||||
* Parse entry points case sensitively. Closes #68
|
||||
* Add a version constraint on the backport configparser package. Closes #66
|
||||
|
||||
0.17
|
||||
====
|
||||
* Fix a permission problem in the tests on Windows.
|
||||
|
||||
0.16
|
||||
====
|
||||
* Don't crash if there exists an EGG-INFO directory on sys.path.
|
||||
|
||||
0.15
|
||||
====
|
||||
* Fix documentation.
|
||||
|
||||
0.14
|
||||
====
|
||||
* Removed ``local_distribution`` function from the API.
|
||||
**This backward-incompatible change removes this
|
||||
behavior summarily**. Projects should remove their
|
||||
reliance on this behavior. A replacement behavior is
|
||||
under review in the `pep517 project
|
||||
<https://github.com/pypa/pep517>`_. Closes #42.
|
||||
|
||||
0.13
|
||||
====
|
||||
* Update docstrings to match PEP 8. Closes #63.
|
||||
* Merged modules into one module. Closes #62.
|
||||
|
||||
0.12
|
||||
====
|
||||
* Add support for eggs. !65; Closes #19.
|
||||
|
||||
0.11
|
||||
====
|
||||
* Support generic zip files (not just wheels). Closes #59
|
||||
* Support zip files with multiple distributions in them. Closes #60
|
||||
* Fully expose the public API in ``importlib_metadata.__all__``.
|
||||
|
||||
0.10
|
||||
====
|
||||
* The ``Distribution`` ABC is now officially part of the public API.
|
||||
Closes #37.
|
||||
* Fixed support for older single file egg-info formats. Closes #43.
|
||||
* Fixed a testing bug when ``$CWD`` has spaces in the path. Closes #50.
|
||||
* Add Python 3.8 to the ``tox`` testing matrix.
|
||||
|
||||
0.9
|
||||
===
|
||||
* Fixed issue where entry points without an attribute would raise an
|
||||
Exception. Closes #40.
|
||||
* Removed unused ``name`` parameter from ``entry_points()``. Closes #44.
|
||||
* ``DistributionFinder`` classes must now be instantiated before
|
||||
being placed on ``sys.meta_path``.
|
||||
|
||||
0.8
|
||||
===
|
||||
* This library can now discover/enumerate all installed packages. **This
|
||||
backward-incompatible change alters the protocol finders must
|
||||
implement to support distribution package discovery.** Closes #24.
|
||||
* The signature of ``find_distributions()`` on custom installer finders
|
||||
should now accept two parameters, ``name`` and ``path`` and
|
||||
these parameters must supply defaults.
|
||||
* The ``entry_points()`` method no longer accepts a package name
|
||||
but instead returns all entry points in a dictionary keyed by the
|
||||
``EntryPoint.group``. The ``resolve`` method has been removed. Instead,
|
||||
call ``EntryPoint.load()``, which has the same semantics as
|
||||
``pkg_resources`` and ``entrypoints``. **This is a backward incompatible
|
||||
change.**
|
||||
* Metadata is now always returned as Unicode text regardless of
|
||||
Python version. Closes #29.
|
||||
* This library can now discover metadata for a 'local' package (found
|
||||
in the current-working directory). Closes #27.
|
||||
* Added ``files()`` function for resolving files from a distribution.
|
||||
* Added a new ``requires()`` function, which returns the requirements
|
||||
for a package suitable for parsing by
|
||||
``packaging.requirements.Requirement``. Closes #18.
|
||||
* The top-level ``read_text()`` function has been removed. Use
|
||||
``PackagePath.read_text()`` on instances returned by the ``files()``
|
||||
function. **This is a backward incompatible change.**
|
||||
* Release dates are now automatically injected into the changelog
|
||||
based on SCM tags.
|
||||
|
||||
0.7
|
||||
===
|
||||
* Fixed issue where packages with dashes in their names would
|
||||
not be discovered. Closes #21.
|
||||
* Distribution lookup is now case-insensitive. Closes #20.
|
||||
* Wheel distributions can no longer be discovered by their module
|
||||
name. Like Path distributions, they must be indicated by their
|
||||
distribution package name.
|
||||
|
||||
0.6
|
||||
===
|
||||
* Removed ``importlib_metadata.distribution`` function. Now
|
||||
the public interface is primarily the utility functions exposed
|
||||
in ``importlib_metadata.__all__``. Closes #14.
|
||||
* Added two new utility functions ``read_text`` and
|
||||
``metadata``.
|
||||
|
||||
0.5
|
||||
===
|
||||
* Updated README and removed details about Distribution
|
||||
class, now considered private. Closes #15.
|
||||
* Added test suite support for Python 3.4+.
|
||||
* Fixed SyntaxErrors on Python 3.4 and 3.5. !12
|
||||
* Fixed errors on Windows joining Path elements. !15
|
||||
|
||||
0.4
|
||||
===
|
||||
* Housekeeping.
|
||||
|
||||
0.3
|
||||
===
|
||||
* Added usage documentation. Closes #8
|
||||
* Add support for getting metadata from wheels on ``sys.path``. Closes #9
|
||||
|
||||
0.2
|
||||
===
|
||||
* Added ``importlib_metadata.entry_points()``. Closes #1
|
||||
* Added ``importlib_metadata.resolve()``. Closes #12
|
||||
* Add support for Python 2.7. Closes #4
|
||||
|
||||
0.1
|
||||
===
|
||||
* Initial release.
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: change-log-mode
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 78
|
||||
coding: utf-8
|
||||
End:
|
||||
185
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/conf.py
vendored
Normal file
185
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/conf.py
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# importlib_metadata documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Nov 30 10:21:00 2017.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'rst.linker',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'importlib_metadata'
|
||||
copyright = '2017-2019, Jason R. Coombs, Barry Warsaw'
|
||||
author = 'Jason R. Coombs, Barry Warsaw'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'default'
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'relations.html', # needs 'show_related': True theme option to display
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'importlib_metadatadoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'importlib_metadata.tex',
|
||||
'importlib\\_metadata Documentation',
|
||||
'Brett Cannon, Barry Warsaw', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'importlib_metadata', 'importlib_metadata Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'importlib_metadata', 'importlib_metadata Documentation',
|
||||
author, 'importlib_metadata', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {
|
||||
'python': ('https://docs.python.org/3', None),
|
||||
'importlib_resources': (
|
||||
'https://importlib-resources.readthedocs.io/en/latest/', None
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# For rst.linker, inject release dates into changelog.rst
|
||||
link_files = {
|
||||
'changelog.rst': dict(
|
||||
replace=[
|
||||
dict(
|
||||
pattern=r'^(?m)((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n',
|
||||
with_scm='{text}\n{rev[timestamp]:%Y-%m-%d}\n\n',
|
||||
),
|
||||
],
|
||||
),
|
||||
}
|
||||
50
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/index.rst
vendored
Normal file
50
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/index.rst
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
===============================
|
||||
Welcome to importlib_metadata
|
||||
===============================
|
||||
|
||||
``importlib_metadata`` is a library which provides an API for accessing an
|
||||
installed package's metadata (see :pep:`566`), such as its entry points or its top-level
|
||||
name. This functionality intends to replace most uses of ``pkg_resources``
|
||||
`entry point API`_ and `metadata API`_. Along with :mod:`importlib.resources` in
|
||||
Python 3.7 and newer (backported as :doc:`importlib_resources <importlib_resources:index>` for older
|
||||
versions of Python), this can eliminate the need to use the older and less
|
||||
efficient ``pkg_resources`` package.
|
||||
|
||||
``importlib_metadata`` is a backport of Python 3.8's standard library
|
||||
:doc:`importlib.metadata <library/importlib.metadata>` module for Python 2.7, and 3.4 through 3.7. Users of
|
||||
Python 3.8 and beyond are encouraged to use the standard library module.
|
||||
When imported on Python 3.8 and later, ``importlib_metadata`` replaces the
|
||||
DistributionFinder behavior from the stdlib, but leaves the API in tact.
|
||||
Developers looking for detailed API descriptions should refer to the Python
|
||||
3.8 standard library documentation.
|
||||
|
||||
The documentation here includes a general :ref:`usage <using>` guide.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
using.rst
|
||||
changelog (links).rst
|
||||
|
||||
|
||||
Project details
|
||||
===============
|
||||
|
||||
* Project home: https://gitlab.com/python-devs/importlib_metadata
|
||||
* Report bugs at: https://gitlab.com/python-devs/importlib_metadata/issues
|
||||
* Code hosting: https://gitlab.com/python-devs/importlib_metadata.git
|
||||
* Documentation: http://importlib_metadata.readthedocs.io/
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
|
||||
.. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
|
||||
.. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api
|
||||
260
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/using.rst
vendored
Normal file
260
Lib/site-packages/pipenv/vendor/importlib_metadata/docs/using.rst
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
.. _using:
|
||||
|
||||
=================================
|
||||
Using :mod:`!importlib_metadata`
|
||||
=================================
|
||||
|
||||
``importlib_metadata`` is a library that provides for access to installed
|
||||
package metadata. Built in part on Python's import system, this library
|
||||
intends to replace similar functionality in the `entry point
|
||||
API`_ and `metadata API`_ of ``pkg_resources``. Along with
|
||||
:mod:`importlib.resources` in Python 3.7
|
||||
and newer (backported as :doc:`importlib_resources <importlib_resources:index>` for older versions of
|
||||
Python), this can eliminate the need to use the older and less efficient
|
||||
``pkg_resources`` package.
|
||||
|
||||
By "installed package" we generally mean a third-party package installed into
|
||||
Python's ``site-packages`` directory via tools such as `pip
|
||||
<https://pypi.org/project/pip/>`_. Specifically,
|
||||
it means a package with either a discoverable ``dist-info`` or ``egg-info``
|
||||
directory, and metadata defined by :pep:`566` or its older specifications.
|
||||
By default, package metadata can live on the file system or in zip archives on
|
||||
:data:`sys.path`. Through an extension mechanism, the metadata can live almost
|
||||
anywhere.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Let's say you wanted to get the version string for a package you've installed
|
||||
using ``pip``. We start by creating a virtual environment and installing
|
||||
something into it::
|
||||
|
||||
$ python3 -m venv example
|
||||
$ source example/bin/activate
|
||||
(example) $ pip install importlib_metadata
|
||||
(example) $ pip install wheel
|
||||
|
||||
You can get the version string for ``wheel`` by running the following::
|
||||
|
||||
(example) $ python
|
||||
>>> from importlib_metadata import version
|
||||
>>> version('wheel')
|
||||
'0.32.3'
|
||||
|
||||
You can also get the set of entry points keyed by group, such as
|
||||
``console_scripts``, ``distutils.commands`` and others. Each group contains a
|
||||
sequence of :ref:`EntryPoint <entry-points>` objects.
|
||||
|
||||
You can get the :ref:`metadata for a distribution <metadata>`::
|
||||
|
||||
>>> list(metadata('wheel'))
|
||||
['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist']
|
||||
|
||||
You can also get a :ref:`distribution's version number <version>`, list its
|
||||
:ref:`constituent files <files>`, and get a list of the distribution's
|
||||
:ref:`requirements`.
|
||||
|
||||
|
||||
Functional API
|
||||
==============
|
||||
|
||||
This package provides the following functionality via its public API.
|
||||
|
||||
|
||||
.. _entry-points:
|
||||
|
||||
Entry points
|
||||
------------
|
||||
|
||||
The ``entry_points()`` function returns a dictionary of all entry points,
|
||||
keyed by group. Entry points are represented by ``EntryPoint`` instances;
|
||||
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
|
||||
a ``.load()`` method to resolve the value. There are also ``.module``,
|
||||
``.attr``, and ``.extras`` attributes for getting the components of the
|
||||
``.value`` attribute::
|
||||
|
||||
>>> eps = entry_points()
|
||||
>>> list(eps)
|
||||
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
|
||||
>>> scripts = eps['console_scripts']
|
||||
>>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0]
|
||||
>>> wheel
|
||||
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
|
||||
>>> wheel.module
|
||||
'wheel.cli'
|
||||
>>> wheel.attr
|
||||
'main'
|
||||
>>> wheel.extras
|
||||
[]
|
||||
>>> main = wheel.load()
|
||||
>>> main
|
||||
<function main at 0x103528488>
|
||||
|
||||
The ``group`` and ``name`` are arbitrary values defined by the package author
|
||||
and usually a client will wish to resolve all entry points for a particular
|
||||
group. Read `the setuptools docs
|
||||
<https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins>`_
|
||||
for more information on entrypoints, their definition, and usage.
|
||||
|
||||
|
||||
.. _metadata:
|
||||
|
||||
Distribution metadata
|
||||
---------------------
|
||||
|
||||
Every distribution includes some metadata, which you can extract using the
|
||||
``metadata()`` function::
|
||||
|
||||
>>> wheel_metadata = metadata('wheel')
|
||||
|
||||
The keys of the returned data structure [#f1]_ name the metadata keywords, and
|
||||
their values are returned unparsed from the distribution metadata::
|
||||
|
||||
>>> wheel_metadata['Requires-Python']
|
||||
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
|
||||
|
||||
|
||||
.. _version:
|
||||
|
||||
Distribution versions
|
||||
---------------------
|
||||
|
||||
The ``version()`` function is the quickest way to get a distribution's version
|
||||
number, as a string::
|
||||
|
||||
>>> version('wheel')
|
||||
'0.32.3'
|
||||
|
||||
|
||||
.. _files:
|
||||
|
||||
Distribution files
|
||||
------------------
|
||||
|
||||
You can also get the full set of files contained within a distribution. The
|
||||
``files()`` function takes a distribution package name and returns all of the
|
||||
files installed by this distribution. Each file object returned is a
|
||||
``PackagePath``, a :class:`pathlib.Path` derived object with additional ``dist``,
|
||||
``size``, and ``hash`` properties as indicated by the metadata. For example::
|
||||
|
||||
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]
|
||||
>>> util
|
||||
PackagePath('wheel/util.py')
|
||||
>>> util.size
|
||||
859
|
||||
>>> util.dist
|
||||
<importlib_metadata._hooks.PathDistribution object at 0x101e0cef0>
|
||||
>>> util.hash
|
||||
<FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI>
|
||||
|
||||
Once you have the file, you can also read its contents::
|
||||
|
||||
>>> print(util.read_text())
|
||||
import base64
|
||||
import sys
|
||||
...
|
||||
def as_bytes(s):
|
||||
if isinstance(s, text_type):
|
||||
return s.encode('utf-8')
|
||||
return s
|
||||
|
||||
In the case where the metadata file listing files
|
||||
(RECORD or SOURCES.txt) is missing, ``files()`` will
|
||||
return ``None``. The caller may wish to wrap calls to
|
||||
``files()`` in `always_iterable
|
||||
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_
|
||||
or otherwise guard against this condition if the target
|
||||
distribution is not known to have the metadata present.
|
||||
|
||||
.. _requirements:
|
||||
|
||||
Distribution requirements
|
||||
-------------------------
|
||||
|
||||
To get the full set of requirements for a distribution, use the ``requires()``
|
||||
function::
|
||||
|
||||
>>> requires('wheel')
|
||||
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
|
||||
|
||||
|
||||
Distributions
|
||||
=============
|
||||
|
||||
While the above API is the most common and convenient usage, you can get all
|
||||
of that information from the ``Distribution`` class. A ``Distribution`` is an
|
||||
abstract object that represents the metadata for a Python package. You can
|
||||
get the ``Distribution`` instance::
|
||||
|
||||
>>> from importlib_metadata import distribution
|
||||
>>> dist = distribution('wheel')
|
||||
|
||||
Thus, an alternative way to get the version number is through the
|
||||
``Distribution`` instance::
|
||||
|
||||
>>> dist.version
|
||||
'0.32.3'
|
||||
|
||||
There are all kinds of additional metadata available on the ``Distribution``
|
||||
instance::
|
||||
|
||||
>>> d.metadata['Requires-Python']
|
||||
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
|
||||
>>> d.metadata['License']
|
||||
'MIT'
|
||||
|
||||
The full set of available metadata is not described here. See :pep:`566`
|
||||
for additional details.
|
||||
|
||||
|
||||
Extending the search algorithm
|
||||
==============================
|
||||
|
||||
Because package metadata is not available through :data:`sys.path` searches, or
|
||||
package loaders directly, the metadata for a package is found through import
|
||||
system `finders`_. To find a distribution package's metadata,
|
||||
``importlib.metadata`` queries the list of :term:`meta path finders <meta path finder>` on
|
||||
:data:`sys.meta_path`.
|
||||
|
||||
By default ``importlib_metadata`` installs a finder for distribution packages
|
||||
found on the file system. This finder doesn't actually find any *packages*,
|
||||
but it can find the packages' metadata.
|
||||
|
||||
The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the
|
||||
interface expected of finders by Python's import system.
|
||||
``importlib_metadata`` extends this protocol by looking for an optional
|
||||
``find_distributions`` callable on the finders from
|
||||
:data:`sys.meta_path` and presents this extended interface as the
|
||||
``DistributionFinder`` abstract base class, which defines this abstract
|
||||
method::
|
||||
|
||||
@abc.abstractmethod
|
||||
def find_distributions(context=DistributionFinder.Context()):
|
||||
"""Return an iterable of all Distribution instances capable of
|
||||
loading the metadata for packages for the indicated ``context``.
|
||||
"""
|
||||
|
||||
The ``DistributionFinder.Context`` object provides ``.path`` and ``.name``
|
||||
properties indicating the path to search and names to match and may
|
||||
supply other relevant context.
|
||||
|
||||
What this means in practice is that to support finding distribution package
|
||||
metadata in locations other than the file system, subclass
|
||||
``Distribution`` and implement the abstract methods. Then from
|
||||
a custom finder, return instances of this derived ``Distribution`` in the
|
||||
``find_distributions()`` method.
|
||||
|
||||
|
||||
.. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
|
||||
.. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api
|
||||
.. _`finders`: https://docs.python.org/3/reference/import.html#finders-and-loaders
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#f1] Technically, the returned distribution metadata object is an
|
||||
:class:`email.message.EmailMessage`
|
||||
instance, but this is an implementation detail, and not part of the
|
||||
stable API. You should only use dictionary-like methods and syntax
|
||||
to access the metadata contents.
|
||||
0
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__init__.py
vendored
Normal file
0
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__init__.py
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/fixtures.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/fixtures.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_api.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_api.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_integration.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_integration.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_main.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_main.cpython-38.pyc
vendored
Normal file
Binary file not shown.
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_zip.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/__pycache__/test_zip.cpython-38.pyc
vendored
Normal file
Binary file not shown.
0
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/data/__init__.py
vendored
Normal file
0
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/data/__init__.py
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/data/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
BIN
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/data/__pycache__/__init__.cpython-38.pyc
vendored
Normal file
Binary file not shown.
210
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/fixtures.py
vendored
Normal file
210
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/fixtures.py
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
from .._compat import pathlib, contextlib
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def tempdir():
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
try:
|
||||
yield pathlib.Path(tmpdir)
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def save_cwd():
|
||||
orig = os.getcwd()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(orig)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def tempdir_as_cwd():
|
||||
with tempdir() as tmp:
|
||||
with save_cwd():
|
||||
os.chdir(str(tmp))
|
||||
yield tmp
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def install_finder(finder):
|
||||
sys.meta_path.append(finder)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.meta_path.remove(finder)
|
||||
|
||||
|
||||
class Fixtures:
|
||||
def setUp(self):
|
||||
self.fixtures = contextlib.ExitStack()
|
||||
self.addCleanup(self.fixtures.close)
|
||||
|
||||
|
||||
class SiteDir(Fixtures):
|
||||
def setUp(self):
|
||||
super(SiteDir, self).setUp()
|
||||
self.site_dir = self.fixtures.enter_context(tempdir())
|
||||
|
||||
|
||||
class OnSysPath(Fixtures):
|
||||
@staticmethod
|
||||
@contextlib.contextmanager
|
||||
def add_sys_path(dir):
|
||||
sys.path[:0] = [str(dir)]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.path.remove(str(dir))
|
||||
|
||||
def setUp(self):
|
||||
super(OnSysPath, self).setUp()
|
||||
self.fixtures.enter_context(self.add_sys_path(self.site_dir))
|
||||
|
||||
|
||||
class DistInfoPkg(OnSysPath, SiteDir):
|
||||
files = {
|
||||
"distinfo_pkg-1.0.0.dist-info": {
|
||||
"METADATA": """
|
||||
Name: distinfo-pkg
|
||||
Author: Steven Ma
|
||||
Version: 1.0.0
|
||||
Requires-Dist: wheel >= 1.0
|
||||
Requires-Dist: pytest; extra == 'test'
|
||||
""",
|
||||
"RECORD": "mod.py,sha256=abc,20\n",
|
||||
"entry_points.txt": """
|
||||
[entries]
|
||||
main = mod:main
|
||||
ns:sub = mod:main
|
||||
"""
|
||||
},
|
||||
"mod.py": """
|
||||
def main():
|
||||
print("hello world")
|
||||
""",
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(DistInfoPkg, self).setUp()
|
||||
build_files(DistInfoPkg.files, self.site_dir)
|
||||
|
||||
|
||||
class DistInfoPkgOffPath(SiteDir):
|
||||
def setUp(self):
|
||||
super(DistInfoPkgOffPath, self).setUp()
|
||||
build_files(DistInfoPkg.files, self.site_dir)
|
||||
|
||||
|
||||
class EggInfoPkg(OnSysPath, SiteDir):
|
||||
files = {
|
||||
"egginfo_pkg.egg-info": {
|
||||
"PKG-INFO": """
|
||||
Name: egginfo-pkg
|
||||
Author: Steven Ma
|
||||
License: Unknown
|
||||
Version: 1.0.0
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
""",
|
||||
"SOURCES.txt": """
|
||||
mod.py
|
||||
egginfo_pkg.egg-info/top_level.txt
|
||||
""",
|
||||
"entry_points.txt": """
|
||||
[entries]
|
||||
main = mod:main
|
||||
""",
|
||||
"requires.txt": """
|
||||
wheel >= 1.0; python_version >= "2.7"
|
||||
[test]
|
||||
pytest
|
||||
""",
|
||||
"top_level.txt": "mod\n"
|
||||
},
|
||||
"mod.py": """
|
||||
def main():
|
||||
print("hello world")
|
||||
""",
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(EggInfoPkg, self).setUp()
|
||||
build_files(EggInfoPkg.files, prefix=self.site_dir)
|
||||
|
||||
|
||||
class EggInfoFile(OnSysPath, SiteDir):
|
||||
files = {
|
||||
"egginfo_file.egg-info": """
|
||||
Metadata-Version: 1.0
|
||||
Name: egginfo_file
|
||||
Version: 0.1
|
||||
Summary: An example package
|
||||
Home-page: www.example.com
|
||||
Author: Eric Haffa-Vee
|
||||
Author-email: eric@example.coms
|
||||
License: UNKNOWN
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
""",
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(EggInfoFile, self).setUp()
|
||||
build_files(EggInfoFile.files, prefix=self.site_dir)
|
||||
|
||||
|
||||
def build_files(file_defs, prefix=pathlib.Path()):
|
||||
"""Build a set of files/directories, as described by the
|
||||
|
||||
file_defs dictionary. Each key/value pair in the dictionary is
|
||||
interpreted as a filename/contents pair. If the contents value is a
|
||||
dictionary, a directory is created, and the dictionary interpreted
|
||||
as the files within it, recursively.
|
||||
|
||||
For example:
|
||||
|
||||
{"README.txt": "A README file",
|
||||
"foo": {
|
||||
"__init__.py": "",
|
||||
"bar": {
|
||||
"__init__.py": "",
|
||||
},
|
||||
"baz.py": "# Some code",
|
||||
}
|
||||
}
|
||||
"""
|
||||
for name, contents in file_defs.items():
|
||||
full_name = prefix / name
|
||||
if isinstance(contents, dict):
|
||||
full_name.mkdir()
|
||||
build_files(contents, prefix=full_name)
|
||||
else:
|
||||
if isinstance(contents, bytes):
|
||||
with full_name.open('wb') as f:
|
||||
f.write(contents)
|
||||
else:
|
||||
with full_name.open('w') as f:
|
||||
f.write(DALS(contents))
|
||||
|
||||
|
||||
def DALS(str):
|
||||
"Dedent and left-strip"
|
||||
return textwrap.dedent(str).lstrip()
|
||||
|
||||
|
||||
class NullFinder:
|
||||
def find_module(self, name):
|
||||
pass
|
||||
176
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_api.py
vendored
Normal file
176
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_api.py
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
import re
|
||||
import textwrap
|
||||
import unittest
|
||||
|
||||
from . import fixtures
|
||||
from .. import (
|
||||
Distribution, PackageNotFoundError, __version__, distribution,
|
||||
entry_points, files, metadata, requires, version,
|
||||
)
|
||||
|
||||
try:
|
||||
from collections.abc import Iterator
|
||||
except ImportError:
|
||||
from collections import Iterator # noqa: F401
|
||||
|
||||
try:
|
||||
from builtins import str as text
|
||||
except ImportError:
|
||||
from __builtin__ import unicode as text
|
||||
|
||||
|
||||
class APITests(
|
||||
fixtures.EggInfoPkg,
|
||||
fixtures.DistInfoPkg,
|
||||
fixtures.EggInfoFile,
|
||||
unittest.TestCase):
|
||||
|
||||
version_pattern = r'\d+\.\d+(\.\d)?'
|
||||
|
||||
def test_retrieves_version_of_self(self):
|
||||
pkg_version = version('egginfo-pkg')
|
||||
assert isinstance(pkg_version, text)
|
||||
assert re.match(self.version_pattern, pkg_version)
|
||||
|
||||
def test_retrieves_version_of_distinfo_pkg(self):
|
||||
pkg_version = version('distinfo-pkg')
|
||||
assert isinstance(pkg_version, text)
|
||||
assert re.match(self.version_pattern, pkg_version)
|
||||
|
||||
def test_for_name_does_not_exist(self):
|
||||
with self.assertRaises(PackageNotFoundError):
|
||||
distribution('does-not-exist')
|
||||
|
||||
def test_for_top_level(self):
|
||||
self.assertEqual(
|
||||
distribution('egginfo-pkg').read_text('top_level.txt').strip(),
|
||||
'mod')
|
||||
|
||||
def test_read_text(self):
|
||||
top_level = [
|
||||
path for path in files('egginfo-pkg')
|
||||
if path.name == 'top_level.txt'
|
||||
][0]
|
||||
self.assertEqual(top_level.read_text(), 'mod\n')
|
||||
|
||||
def test_entry_points(self):
|
||||
entries = dict(entry_points()['entries'])
|
||||
ep = entries['main']
|
||||
self.assertEqual(ep.value, 'mod:main')
|
||||
self.assertEqual(ep.extras, [])
|
||||
|
||||
def test_metadata_for_this_package(self):
|
||||
md = metadata('egginfo-pkg')
|
||||
assert md['author'] == 'Steven Ma'
|
||||
assert md['LICENSE'] == 'Unknown'
|
||||
assert md['Name'] == 'egginfo-pkg'
|
||||
classifiers = md.get_all('Classifier')
|
||||
assert 'Topic :: Software Development :: Libraries' in classifiers
|
||||
|
||||
def test_importlib_metadata_version(self):
|
||||
assert re.match(self.version_pattern, __version__)
|
||||
|
||||
@staticmethod
|
||||
def _test_files(files):
|
||||
root = files[0].root
|
||||
for file in files:
|
||||
assert file.root == root
|
||||
assert not file.hash or file.hash.value
|
||||
assert not file.hash or file.hash.mode == 'sha256'
|
||||
assert not file.size or file.size >= 0
|
||||
assert file.locate().exists()
|
||||
assert isinstance(file.read_binary(), bytes)
|
||||
if file.name.endswith('.py'):
|
||||
file.read_text()
|
||||
|
||||
def test_file_hash_repr(self):
|
||||
try:
|
||||
assertRegex = self.assertRegex
|
||||
except AttributeError:
|
||||
# Python 2
|
||||
assertRegex = self.assertRegexpMatches
|
||||
|
||||
util = [
|
||||
p for p in files('distinfo-pkg')
|
||||
if p.name == 'mod.py'
|
||||
][0]
|
||||
assertRegex(
|
||||
repr(util.hash),
|
||||
'<FileHash mode: sha256 value: .*>')
|
||||
|
||||
def test_files_dist_info(self):
|
||||
self._test_files(files('distinfo-pkg'))
|
||||
|
||||
def test_files_egg_info(self):
|
||||
self._test_files(files('egginfo-pkg'))
|
||||
|
||||
def test_version_egg_info_file(self):
|
||||
self.assertEqual(version('egginfo-file'), '0.1')
|
||||
|
||||
def test_requires_egg_info_file(self):
|
||||
requirements = requires('egginfo-file')
|
||||
self.assertIsNone(requirements)
|
||||
|
||||
def test_requires_egg_info(self):
|
||||
deps = requires('egginfo-pkg')
|
||||
assert len(deps) == 2
|
||||
assert any(
|
||||
dep == 'wheel >= 1.0; python_version >= "2.7"'
|
||||
for dep in deps
|
||||
)
|
||||
|
||||
def test_requires_dist_info(self):
|
||||
deps = requires('distinfo-pkg')
|
||||
assert len(deps) == 2
|
||||
assert all(deps)
|
||||
assert 'wheel >= 1.0' in deps
|
||||
assert "pytest; extra == 'test'" in deps
|
||||
|
||||
def test_more_complex_deps_requires_text(self):
|
||||
requires = textwrap.dedent("""
|
||||
dep1
|
||||
dep2
|
||||
|
||||
[:python_version < "3"]
|
||||
dep3
|
||||
|
||||
[extra1]
|
||||
dep4
|
||||
|
||||
[extra2:python_version < "3"]
|
||||
dep5
|
||||
""")
|
||||
deps = sorted(Distribution._deps_from_requires_text(requires))
|
||||
expected = [
|
||||
'dep1',
|
||||
'dep2',
|
||||
'dep3; python_version < "3"',
|
||||
'dep4; extra == "extra1"',
|
||||
'dep5; (python_version < "3") and extra == "extra2"',
|
||||
]
|
||||
# It's important that the environment marker expression be
|
||||
# wrapped in parentheses to avoid the following 'and' binding more
|
||||
# tightly than some other part of the environment expression.
|
||||
|
||||
assert deps == expected
|
||||
|
||||
|
||||
class OffSysPathTests(fixtures.DistInfoPkgOffPath, unittest.TestCase):
|
||||
def test_find_distributions_specified_path(self):
|
||||
dists = Distribution.discover(path=[str(self.site_dir)])
|
||||
assert any(
|
||||
dist.metadata['Name'] == 'distinfo-pkg'
|
||||
for dist in dists
|
||||
)
|
||||
|
||||
def test_distribution_at_pathlib(self):
|
||||
"""Demonstrate how to load metadata direct from a directory.
|
||||
"""
|
||||
dist_info_path = self.site_dir / 'distinfo_pkg-1.0.0.dist-info'
|
||||
dist = Distribution.at(dist_info_path)
|
||||
assert dist.version == '1.0.0'
|
||||
|
||||
def test_distribution_at_str(self):
|
||||
dist_info_path = self.site_dir / 'distinfo_pkg-1.0.0.dist-info'
|
||||
dist = Distribution.at(str(dist_info_path))
|
||||
assert dist.version == '1.0.0'
|
||||
42
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_integration.py
vendored
Normal file
42
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_integration.py
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import unittest
|
||||
import packaging.requirements
|
||||
import packaging.version
|
||||
|
||||
from . import fixtures
|
||||
from .. import (
|
||||
_compat,
|
||||
version,
|
||||
)
|
||||
|
||||
|
||||
class IntegrationTests(fixtures.DistInfoPkg, unittest.TestCase):
|
||||
|
||||
def test_package_spec_installed(self):
|
||||
"""
|
||||
Illustrate the recommended procedure to determine if
|
||||
a specified version of a package is installed.
|
||||
"""
|
||||
def is_installed(package_spec):
|
||||
req = packaging.requirements.Requirement(package_spec)
|
||||
return version(req.name) in req.specifier
|
||||
|
||||
assert is_installed('distinfo-pkg==1.0')
|
||||
assert is_installed('distinfo-pkg>=1.0,<2.0')
|
||||
assert not is_installed('distinfo-pkg<1.0')
|
||||
|
||||
|
||||
class FinderTests(fixtures.Fixtures, unittest.TestCase):
|
||||
|
||||
def test_finder_without_module(self):
|
||||
class ModuleFreeFinder(fixtures.NullFinder):
|
||||
"""
|
||||
A finder without an __module__ attribute
|
||||
"""
|
||||
def __getattribute__(self, name):
|
||||
if name == '__module__':
|
||||
raise AttributeError(name)
|
||||
return super().__getattribute__(name)
|
||||
|
||||
self.fixtures.enter_context(
|
||||
fixtures.install_finder(ModuleFreeFinder()))
|
||||
_compat.disable_stdlib_finder()
|
||||
258
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_main.py
vendored
Normal file
258
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_main.py
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
import json
|
||||
import pickle
|
||||
import textwrap
|
||||
import unittest
|
||||
import importlib
|
||||
import importlib_metadata
|
||||
import pyfakefs.fake_filesystem_unittest as ffs
|
||||
|
||||
from . import fixtures
|
||||
from .. import (
|
||||
Distribution, EntryPoint, MetadataPathFinder,
|
||||
PackageNotFoundError, distributions,
|
||||
entry_points, metadata, version,
|
||||
)
|
||||
|
||||
try:
|
||||
from builtins import str as text
|
||||
except ImportError:
|
||||
from __builtin__ import unicode as text
|
||||
|
||||
|
||||
class BasicTests(fixtures.DistInfoPkg, unittest.TestCase):
|
||||
version_pattern = r'\d+\.\d+(\.\d)?'
|
||||
|
||||
def test_retrieves_version_of_self(self):
|
||||
dist = Distribution.from_name('distinfo-pkg')
|
||||
assert isinstance(dist.version, text)
|
||||
assert re.match(self.version_pattern, dist.version)
|
||||
|
||||
def test_for_name_does_not_exist(self):
|
||||
with self.assertRaises(PackageNotFoundError):
|
||||
Distribution.from_name('does-not-exist')
|
||||
|
||||
def test_new_style_classes(self):
|
||||
self.assertIsInstance(Distribution, type)
|
||||
self.assertIsInstance(MetadataPathFinder, type)
|
||||
|
||||
|
||||
class ImportTests(fixtures.DistInfoPkg, unittest.TestCase):
|
||||
def test_import_nonexistent_module(self):
|
||||
# Ensure that the MetadataPathFinder does not crash an import of a
|
||||
# non-existent module.
|
||||
with self.assertRaises(ImportError):
|
||||
importlib.import_module('does_not_exist')
|
||||
|
||||
def test_resolve(self):
|
||||
entries = dict(entry_points()['entries'])
|
||||
ep = entries['main']
|
||||
self.assertEqual(ep.load().__name__, "main")
|
||||
|
||||
def test_entrypoint_with_colon_in_name(self):
|
||||
entries = dict(entry_points()['entries'])
|
||||
ep = entries['ns:sub']
|
||||
self.assertEqual(ep.value, 'mod:main')
|
||||
|
||||
def test_resolve_without_attr(self):
|
||||
ep = EntryPoint(
|
||||
name='ep',
|
||||
value='importlib_metadata',
|
||||
group='grp',
|
||||
)
|
||||
assert ep.load() is importlib_metadata
|
||||
|
||||
|
||||
class NameNormalizationTests(
|
||||
fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
|
||||
@staticmethod
|
||||
def pkg_with_dashes(site_dir):
|
||||
"""
|
||||
Create minimal metadata for a package with dashes
|
||||
in the name (and thus underscores in the filename).
|
||||
"""
|
||||
metadata_dir = site_dir / 'my_pkg.dist-info'
|
||||
metadata_dir.mkdir()
|
||||
metadata = metadata_dir / 'METADATA'
|
||||
with metadata.open('w') as strm:
|
||||
strm.write('Version: 1.0\n')
|
||||
return 'my-pkg'
|
||||
|
||||
def test_dashes_in_dist_name_found_as_underscores(self):
|
||||
"""
|
||||
For a package with a dash in the name, the dist-info metadata
|
||||
uses underscores in the name. Ensure the metadata loads.
|
||||
"""
|
||||
pkg_name = self.pkg_with_dashes(self.site_dir)
|
||||
assert version(pkg_name) == '1.0'
|
||||
|
||||
@staticmethod
|
||||
def pkg_with_mixed_case(site_dir):
|
||||
"""
|
||||
Create minimal metadata for a package with mixed case
|
||||
in the name.
|
||||
"""
|
||||
metadata_dir = site_dir / 'CherryPy.dist-info'
|
||||
metadata_dir.mkdir()
|
||||
metadata = metadata_dir / 'METADATA'
|
||||
with metadata.open('w') as strm:
|
||||
strm.write('Version: 1.0\n')
|
||||
return 'CherryPy'
|
||||
|
||||
def test_dist_name_found_as_any_case(self):
|
||||
"""
|
||||
Ensure the metadata loads when queried with any case.
|
||||
"""
|
||||
pkg_name = self.pkg_with_mixed_case(self.site_dir)
|
||||
assert version(pkg_name) == '1.0'
|
||||
assert version(pkg_name.lower()) == '1.0'
|
||||
assert version(pkg_name.upper()) == '1.0'
|
||||
|
||||
|
||||
class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
|
||||
@staticmethod
|
||||
def pkg_with_non_ascii_description(site_dir):
|
||||
"""
|
||||
Create minimal metadata for a package with non-ASCII in
|
||||
the description.
|
||||
"""
|
||||
metadata_dir = site_dir / 'portend.dist-info'
|
||||
metadata_dir.mkdir()
|
||||
metadata = metadata_dir / 'METADATA'
|
||||
with metadata.open('w', encoding='utf-8') as fp:
|
||||
fp.write('Description: pôrˈtend\n')
|
||||
return 'portend'
|
||||
|
||||
@staticmethod
|
||||
def pkg_with_non_ascii_description_egg_info(site_dir):
|
||||
"""
|
||||
Create minimal metadata for an egg-info package with
|
||||
non-ASCII in the description.
|
||||
"""
|
||||
metadata_dir = site_dir / 'portend.dist-info'
|
||||
metadata_dir.mkdir()
|
||||
metadata = metadata_dir / 'METADATA'
|
||||
with metadata.open('w', encoding='utf-8') as fp:
|
||||
fp.write(textwrap.dedent("""
|
||||
Name: portend
|
||||
|
||||
pôrˈtend
|
||||
""").lstrip())
|
||||
return 'portend'
|
||||
|
||||
def test_metadata_loads(self):
|
||||
pkg_name = self.pkg_with_non_ascii_description(self.site_dir)
|
||||
meta = metadata(pkg_name)
|
||||
assert meta['Description'] == 'pôrˈtend'
|
||||
|
||||
def test_metadata_loads_egg_info(self):
|
||||
pkg_name = self.pkg_with_non_ascii_description_egg_info(self.site_dir)
|
||||
meta = metadata(pkg_name)
|
||||
assert meta.get_payload() == 'pôrˈtend\n'
|
||||
|
||||
|
||||
class DiscoveryTests(fixtures.EggInfoPkg,
|
||||
fixtures.DistInfoPkg,
|
||||
unittest.TestCase):
|
||||
|
||||
def test_package_discovery(self):
|
||||
dists = list(distributions())
|
||||
assert all(
|
||||
isinstance(dist, Distribution)
|
||||
for dist in dists
|
||||
)
|
||||
assert any(
|
||||
dist.metadata['Name'] == 'egginfo-pkg'
|
||||
for dist in dists
|
||||
)
|
||||
assert any(
|
||||
dist.metadata['Name'] == 'distinfo-pkg'
|
||||
for dist in dists
|
||||
)
|
||||
|
||||
def test_invalid_usage(self):
|
||||
with self.assertRaises(ValueError):
|
||||
list(distributions(context='something', name='else'))
|
||||
|
||||
|
||||
class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
|
||||
def test_egg_info(self):
|
||||
# make an `EGG-INFO` directory that's unrelated
|
||||
self.site_dir.joinpath('EGG-INFO').mkdir()
|
||||
# used to crash with `IsADirectoryError`
|
||||
with self.assertRaises(PackageNotFoundError):
|
||||
version('unknown-package')
|
||||
|
||||
def test_egg(self):
|
||||
egg = self.site_dir.joinpath('foo-3.6.egg')
|
||||
egg.mkdir()
|
||||
with self.add_sys_path(egg):
|
||||
with self.assertRaises(PackageNotFoundError):
|
||||
version('foo')
|
||||
|
||||
|
||||
class MissingSysPath(fixtures.OnSysPath, unittest.TestCase):
|
||||
site_dir = '/does-not-exist'
|
||||
|
||||
def test_discovery(self):
|
||||
"""
|
||||
Discovering distributions should succeed even if
|
||||
there is an invalid path on sys.path.
|
||||
"""
|
||||
importlib_metadata.distributions()
|
||||
|
||||
|
||||
class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase):
|
||||
site_dir = '/access-denied'
|
||||
|
||||
def setUp(self):
|
||||
super(InaccessibleSysPath, self).setUp()
|
||||
self.setUpPyfakefs()
|
||||
self.fs.create_dir(self.site_dir, perm_bits=000)
|
||||
|
||||
def test_discovery(self):
|
||||
"""
|
||||
Discovering distributions should succeed even if
|
||||
there is an invalid path on sys.path.
|
||||
"""
|
||||
list(importlib_metadata.distributions())
|
||||
|
||||
|
||||
class TestEntryPoints(unittest.TestCase):
|
||||
def __init__(self, *args):
|
||||
super(TestEntryPoints, self).__init__(*args)
|
||||
self.ep = importlib_metadata.EntryPoint('name', 'value', 'group')
|
||||
|
||||
def test_entry_point_pickleable(self):
|
||||
revived = pickle.loads(pickle.dumps(self.ep))
|
||||
assert revived == self.ep
|
||||
|
||||
def test_immutable(self):
|
||||
"""EntryPoints should be immutable"""
|
||||
with self.assertRaises(AttributeError):
|
||||
self.ep.name = 'badactor'
|
||||
|
||||
def test_repr(self):
|
||||
assert 'EntryPoint' in repr(self.ep)
|
||||
assert 'name=' in repr(self.ep)
|
||||
assert "'name'" in repr(self.ep)
|
||||
|
||||
def test_hashable(self):
|
||||
"""EntryPoints should be hashable"""
|
||||
hash(self.ep)
|
||||
|
||||
def test_json_dump(self):
|
||||
"""
|
||||
json should not expect to be able to dump an EntryPoint
|
||||
"""
|
||||
with self.assertRaises(Exception):
|
||||
json.dumps(self.ep)
|
||||
|
||||
def test_module(self):
|
||||
assert self.ep.module == 'value'
|
||||
|
||||
def test_attr(self):
|
||||
assert self.ep.attr is None
|
||||
77
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_zip.py
vendored
Normal file
77
Lib/site-packages/pipenv/vendor/importlib_metadata/tests/test_zip.py
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from .. import (
|
||||
distribution, entry_points, files, PackageNotFoundError,
|
||||
version, distributions,
|
||||
)
|
||||
|
||||
try:
|
||||
from importlib.resources import path
|
||||
except ImportError:
|
||||
from importlib_resources import path
|
||||
|
||||
try:
|
||||
from contextlib import ExitStack
|
||||
except ImportError:
|
||||
from contextlib2 import ExitStack
|
||||
|
||||
|
||||
class TestZip(unittest.TestCase):
|
||||
root = 'importlib_metadata.tests.data'
|
||||
|
||||
def setUp(self):
|
||||
# Find the path to the example-*.whl so we can add it to the front of
|
||||
# sys.path, where we'll then try to find the metadata thereof.
|
||||
self.resources = ExitStack()
|
||||
self.addCleanup(self.resources.close)
|
||||
wheel = self.resources.enter_context(
|
||||
path(self.root, 'example-21.12-py3-none-any.whl'))
|
||||
sys.path.insert(0, str(wheel))
|
||||
self.resources.callback(sys.path.pop, 0)
|
||||
|
||||
def test_zip_version(self):
|
||||
self.assertEqual(version('example'), '21.12')
|
||||
|
||||
def test_zip_version_does_not_match(self):
|
||||
with self.assertRaises(PackageNotFoundError):
|
||||
version('definitely-not-installed')
|
||||
|
||||
def test_zip_entry_points(self):
|
||||
scripts = dict(entry_points()['console_scripts'])
|
||||
entry_point = scripts['example']
|
||||
self.assertEqual(entry_point.value, 'example:main')
|
||||
entry_point = scripts['Example']
|
||||
self.assertEqual(entry_point.value, 'example:main')
|
||||
|
||||
def test_missing_metadata(self):
|
||||
self.assertIsNone(distribution('example').read_text('does not exist'))
|
||||
|
||||
def test_case_insensitive(self):
|
||||
self.assertEqual(version('Example'), '21.12')
|
||||
|
||||
def test_files(self):
|
||||
for file in files('example'):
|
||||
path = str(file.dist.locate_file(file))
|
||||
assert '.whl/' in path, path
|
||||
|
||||
def test_one_distribution(self):
|
||||
dists = list(distributions(path=sys.path[:1]))
|
||||
assert len(dists) == 1
|
||||
|
||||
|
||||
class TestEgg(TestZip):
|
||||
def setUp(self):
|
||||
# Find the path to the example-*.egg so we can add it to the front of
|
||||
# sys.path, where we'll then try to find the metadata thereof.
|
||||
self.resources = ExitStack()
|
||||
self.addCleanup(self.resources.close)
|
||||
egg = self.resources.enter_context(
|
||||
path(self.root, 'example-21.12-py3.6.egg'))
|
||||
sys.path.insert(0, str(egg))
|
||||
self.resources.callback(sys.path.pop, 0)
|
||||
|
||||
def test_files(self):
|
||||
for file in files('example'):
|
||||
path = str(file.dist.locate_file(file))
|
||||
assert '.egg/' in path, path
|
||||
Reference in New Issue
Block a user