mirror of https://github.com/pypa/pip
Update vendored `pkg_resources`
This commit is contained in:
parent
e3e7bc34eb
commit
eb7b4ed62e
|
@ -0,0 +1 @@
|
||||||
|
Patch pkg_resources to remove dependency on ``jaraco.text``.
|
|
@ -0,0 +1 @@
|
||||||
|
Update pkg_resources (via setuptools) to 65.6.3
|
|
@ -50,6 +50,8 @@ drop = [
|
||||||
"easy_install.py",
|
"easy_install.py",
|
||||||
"setuptools",
|
"setuptools",
|
||||||
"pkg_resources/_vendor/",
|
"pkg_resources/_vendor/",
|
||||||
|
"_distutils_hack",
|
||||||
|
"distutils-precedence.pth",
|
||||||
"pkg_resources/extern/",
|
"pkg_resources/extern/",
|
||||||
# trim vendored pygments styles and lexers
|
# trim vendored pygments styles and lexers
|
||||||
"pygments/styles/[!_]*.py",
|
"pygments/styles/[!_]*.py",
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
"""Functions brought over from jaraco.text.
|
||||||
|
|
||||||
|
These functions are not supposed to be used within `pip._internal`. These are
|
||||||
|
helper functions brought over from `jaraco.text` to enable vendoring newer
|
||||||
|
copies of `pkg_resources` without having to vendor `jaraco.text` and its entire
|
||||||
|
dependency cone; something that our vendoring setup is not currently capable of
|
||||||
|
handling.
|
||||||
|
|
||||||
|
License reproduced from original source below:
|
||||||
|
|
||||||
|
Copyright Jason R. Coombs
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import functools
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
|
||||||
|
def _nonblank(str):
|
||||||
|
return str and not str.startswith("#")
|
||||||
|
|
||||||
|
|
||||||
|
@functools.singledispatch
|
||||||
|
def yield_lines(iterable):
|
||||||
|
r"""
|
||||||
|
Yield valid lines of a string or iterable.
|
||||||
|
|
||||||
|
>>> list(yield_lines(''))
|
||||||
|
[]
|
||||||
|
>>> list(yield_lines(['foo', 'bar']))
|
||||||
|
['foo', 'bar']
|
||||||
|
>>> list(yield_lines('foo\nbar'))
|
||||||
|
['foo', 'bar']
|
||||||
|
>>> list(yield_lines('\nfoo\n#bar\nbaz #comment'))
|
||||||
|
['foo', 'baz #comment']
|
||||||
|
>>> list(yield_lines(['foo\nbar', 'baz', 'bing\n\n\n']))
|
||||||
|
['foo', 'bar', 'baz', 'bing']
|
||||||
|
"""
|
||||||
|
return itertools.chain.from_iterable(map(yield_lines, iterable))
|
||||||
|
|
||||||
|
|
||||||
|
@yield_lines.register(str)
|
||||||
|
def _(text):
|
||||||
|
return filter(_nonblank, map(str.strip, text.splitlines()))
|
||||||
|
|
||||||
|
|
||||||
|
def drop_comment(line):
|
||||||
|
"""
|
||||||
|
Drop comments.
|
||||||
|
|
||||||
|
>>> drop_comment('foo # bar')
|
||||||
|
'foo'
|
||||||
|
|
||||||
|
A hash without a space may be in a URL.
|
||||||
|
|
||||||
|
>>> drop_comment('http://example.com/foo#bar')
|
||||||
|
'http://example.com/foo#bar'
|
||||||
|
"""
|
||||||
|
return line.partition(" #")[0]
|
||||||
|
|
||||||
|
|
||||||
|
def join_continuation(lines):
|
||||||
|
r"""
|
||||||
|
Join lines continued by a trailing backslash.
|
||||||
|
|
||||||
|
>>> list(join_continuation(['foo \\', 'bar', 'baz']))
|
||||||
|
['foobar', 'baz']
|
||||||
|
>>> list(join_continuation(['foo \\', 'bar', 'baz']))
|
||||||
|
['foobar', 'baz']
|
||||||
|
>>> list(join_continuation(['foo \\', 'bar \\', 'baz']))
|
||||||
|
['foobarbaz']
|
||||||
|
|
||||||
|
Not sure why, but...
|
||||||
|
The character preceeding the backslash is also elided.
|
||||||
|
|
||||||
|
>>> list(join_continuation(['goo\\', 'dly']))
|
||||||
|
['godly']
|
||||||
|
|
||||||
|
A terrible idea, but...
|
||||||
|
If no line is available to continue, suppress the lines.
|
||||||
|
|
||||||
|
>>> list(join_continuation(['foo', 'bar\\', 'baz\\']))
|
||||||
|
['foo']
|
||||||
|
"""
|
||||||
|
lines = iter(lines)
|
||||||
|
for item in lines:
|
||||||
|
while item.endswith("\\"):
|
||||||
|
try:
|
||||||
|
item = item[:-2].strip() + next(lines)
|
||||||
|
except StopIteration:
|
||||||
|
return
|
||||||
|
yield item
|
|
@ -1,19 +1,19 @@
|
||||||
Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com>
|
Copyright Jason R. Coombs
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
of this software and associated documentation files (the "Software"), to
|
||||||
the Software without restriction, including without limitation the rights to
|
deal in the Software without restriction, including without limitation the
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in
|
||||||
copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
SOFTWARE.
|
IN THE SOFTWARE.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# coding: utf-8
|
|
||||||
"""
|
"""
|
||||||
Package resource API
|
Package resource API
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -15,8 +14,6 @@ The package resource API is designed to work with normal filesystem packages,
|
||||||
method.
|
method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
|
@ -41,6 +38,7 @@ import itertools
|
||||||
import inspect
|
import inspect
|
||||||
import ntpath
|
import ntpath
|
||||||
import posixpath
|
import posixpath
|
||||||
|
import importlib
|
||||||
from pkgutil import get_importer
|
from pkgutil import get_importer
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -54,9 +52,6 @@ try:
|
||||||
except NameError:
|
except NameError:
|
||||||
FileExistsError = OSError
|
FileExistsError = OSError
|
||||||
|
|
||||||
from pip._vendor import six
|
|
||||||
from pip._vendor.six.moves import urllib, map, filter
|
|
||||||
|
|
||||||
# capture these to bypass sandboxing
|
# capture these to bypass sandboxing
|
||||||
from os import utime
|
from os import utime
|
||||||
try:
|
try:
|
||||||
|
@ -76,26 +71,23 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
importlib_machinery = None
|
importlib_machinery = None
|
||||||
|
|
||||||
from . import py31compat
|
from pip._internal.utils._jaraco_text import (
|
||||||
|
yield_lines,
|
||||||
|
drop_comment,
|
||||||
|
join_continuation,
|
||||||
|
)
|
||||||
|
|
||||||
from pip._vendor import platformdirs
|
from pip._vendor import platformdirs
|
||||||
from pip._vendor import packaging
|
from pip._vendor import packaging
|
||||||
__import__('pip._vendor.packaging.version')
|
__import__('pip._vendor.packaging.version')
|
||||||
__import__('pip._vendor.packaging.specifiers')
|
__import__('pip._vendor.packaging.specifiers')
|
||||||
__import__('pip._vendor.packaging.requirements')
|
__import__('pip._vendor.packaging.requirements')
|
||||||
__import__('pip._vendor.packaging.markers')
|
__import__('pip._vendor.packaging.markers')
|
||||||
|
__import__('pip._vendor.packaging.utils')
|
||||||
|
|
||||||
|
if sys.version_info < (3, 5):
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
if (3, 0) < sys.version_info < (3, 5):
|
|
||||||
raise RuntimeError("Python 3.5 or later is required")
|
raise RuntimeError("Python 3.5 or later is required")
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
# Those builtin exceptions are only defined in Python 3
|
|
||||||
PermissionError = None
|
|
||||||
NotADirectoryError = None
|
|
||||||
|
|
||||||
# declare some globals that will be defined later to
|
# declare some globals that will be defined later to
|
||||||
# satisfy the linters.
|
# satisfy the linters.
|
||||||
require = None
|
require = None
|
||||||
|
@ -128,6 +120,11 @@ def parse_version(v):
|
||||||
try:
|
try:
|
||||||
return packaging.version.Version(v)
|
return packaging.version.Version(v)
|
||||||
except packaging.version.InvalidVersion:
|
except packaging.version.InvalidVersion:
|
||||||
|
warnings.warn(
|
||||||
|
f"{v} is an invalid version and will not be supported in "
|
||||||
|
"a future release",
|
||||||
|
PkgResourcesDeprecationWarning,
|
||||||
|
)
|
||||||
return packaging.version.LegacyVersion(v)
|
return packaging.version.LegacyVersion(v)
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,10 +175,10 @@ def get_supported_platform():
|
||||||
"""Return this platform's maximum compatible version.
|
"""Return this platform's maximum compatible version.
|
||||||
|
|
||||||
distutils.util.get_platform() normally reports the minimum version
|
distutils.util.get_platform() normally reports the minimum version
|
||||||
of Mac OS X that would be required to *use* extensions produced by
|
of macOS that would be required to *use* extensions produced by
|
||||||
distutils. But what we want when checking compatibility is to know the
|
distutils. But what we want when checking compatibility is to know the
|
||||||
version of Mac OS X that we are *running*. To allow usage of packages that
|
version of macOS that we are *running*. To allow usage of packages that
|
||||||
explicitly require a newer version of Mac OS X, we must also know the
|
explicitly require a newer version of macOS, we must also know the
|
||||||
current version of the OS.
|
current version of the OS.
|
||||||
|
|
||||||
If this condition occurs for any other platform with a version in its
|
If this condition occurs for any other platform with a version in its
|
||||||
|
@ -191,9 +188,9 @@ def get_supported_platform():
|
||||||
m = macosVersionString.match(plat)
|
m = macosVersionString.match(plat)
|
||||||
if m is not None and sys.platform == "darwin":
|
if m is not None and sys.platform == "darwin":
|
||||||
try:
|
try:
|
||||||
plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3))
|
plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# not Mac OS X
|
# not macOS
|
||||||
pass
|
pass
|
||||||
return plat
|
return plat
|
||||||
|
|
||||||
|
@ -364,7 +361,7 @@ def get_provider(moduleOrReq):
|
||||||
return _find_adapter(_provider_factories, loader)(module)
|
return _find_adapter(_provider_factories, loader)(module)
|
||||||
|
|
||||||
|
|
||||||
def _macosx_vers(_cache=[]):
|
def _macos_vers(_cache=[]):
|
||||||
if not _cache:
|
if not _cache:
|
||||||
version = platform.mac_ver()[0]
|
version = platform.mac_ver()[0]
|
||||||
# fallback for MacPorts
|
# fallback for MacPorts
|
||||||
|
@ -380,7 +377,7 @@ def _macosx_vers(_cache=[]):
|
||||||
return _cache[0]
|
return _cache[0]
|
||||||
|
|
||||||
|
|
||||||
def _macosx_arch(machine):
|
def _macos_arch(machine):
|
||||||
return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine)
|
return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine)
|
||||||
|
|
||||||
|
|
||||||
|
@ -388,18 +385,18 @@ def get_build_platform():
|
||||||
"""Return this platform's string for platform-specific distributions
|
"""Return this platform's string for platform-specific distributions
|
||||||
|
|
||||||
XXX Currently this is the same as ``distutils.util.get_platform()``, but it
|
XXX Currently this is the same as ``distutils.util.get_platform()``, but it
|
||||||
needs some hacks for Linux and Mac OS X.
|
needs some hacks for Linux and macOS.
|
||||||
"""
|
"""
|
||||||
from sysconfig import get_platform
|
from sysconfig import get_platform
|
||||||
|
|
||||||
plat = get_platform()
|
plat = get_platform()
|
||||||
if sys.platform == "darwin" and not plat.startswith('macosx-'):
|
if sys.platform == "darwin" and not plat.startswith('macosx-'):
|
||||||
try:
|
try:
|
||||||
version = _macosx_vers()
|
version = _macos_vers()
|
||||||
machine = os.uname()[4].replace(" ", "_")
|
machine = os.uname()[4].replace(" ", "_")
|
||||||
return "macosx-%d.%d-%s" % (
|
return "macosx-%d.%d-%s" % (
|
||||||
int(version[0]), int(version[1]),
|
int(version[0]), int(version[1]),
|
||||||
_macosx_arch(machine),
|
_macos_arch(machine),
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# if someone is running a non-Mac darwin system, this will fall
|
# if someone is running a non-Mac darwin system, this will fall
|
||||||
|
@ -425,7 +422,7 @@ def compatible_platforms(provided, required):
|
||||||
# easy case
|
# easy case
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Mac OS X special cases
|
# macOS special cases
|
||||||
reqMac = macosVersionString.match(required)
|
reqMac = macosVersionString.match(required)
|
||||||
if reqMac:
|
if reqMac:
|
||||||
provMac = macosVersionString.match(provided)
|
provMac = macosVersionString.match(provided)
|
||||||
|
@ -434,7 +431,7 @@ def compatible_platforms(provided, required):
|
||||||
if not provMac:
|
if not provMac:
|
||||||
# this is backwards compatibility for packages built before
|
# this is backwards compatibility for packages built before
|
||||||
# setuptools 0.6. All packages built after this point will
|
# setuptools 0.6. All packages built after this point will
|
||||||
# use the new macosx designation.
|
# use the new macOS designation.
|
||||||
provDarwin = darwinVersionString.match(provided)
|
provDarwin = darwinVersionString.match(provided)
|
||||||
if provDarwin:
|
if provDarwin:
|
||||||
dversion = int(provDarwin.group(1))
|
dversion = int(provDarwin.group(1))
|
||||||
|
@ -442,7 +439,7 @@ def compatible_platforms(provided, required):
|
||||||
if dversion == 7 and macosversion >= "10.3" or \
|
if dversion == 7 and macosversion >= "10.3" or \
|
||||||
dversion == 8 and macosversion >= "10.4":
|
dversion == 8 and macosversion >= "10.4":
|
||||||
return True
|
return True
|
||||||
# egg isn't macosx or legacy darwin
|
# egg isn't macOS or legacy darwin
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# are they the same major version and machine type?
|
# are they the same major version and machine type?
|
||||||
|
@ -475,7 +472,7 @@ run_main = run_script
|
||||||
|
|
||||||
def get_distribution(dist):
|
def get_distribution(dist):
|
||||||
"""Return a current distribution object for a Requirement or string"""
|
"""Return a current distribution object for a Requirement or string"""
|
||||||
if isinstance(dist, six.string_types):
|
if isinstance(dist, str):
|
||||||
dist = Requirement.parse(dist)
|
dist = Requirement.parse(dist)
|
||||||
if isinstance(dist, Requirement):
|
if isinstance(dist, Requirement):
|
||||||
dist = get_provider(dist)
|
dist = get_provider(dist)
|
||||||
|
@ -558,6 +555,7 @@ class WorkingSet:
|
||||||
self.entries = []
|
self.entries = []
|
||||||
self.entry_keys = {}
|
self.entry_keys = {}
|
||||||
self.by_key = {}
|
self.by_key = {}
|
||||||
|
self.normalized_to_canonical_keys = {}
|
||||||
self.callbacks = []
|
self.callbacks = []
|
||||||
|
|
||||||
if entries is None:
|
if entries is None:
|
||||||
|
@ -638,6 +636,14 @@ class WorkingSet:
|
||||||
is returned.
|
is returned.
|
||||||
"""
|
"""
|
||||||
dist = self.by_key.get(req.key)
|
dist = self.by_key.get(req.key)
|
||||||
|
|
||||||
|
if dist is None:
|
||||||
|
canonical_key = self.normalized_to_canonical_keys.get(req.key)
|
||||||
|
|
||||||
|
if canonical_key is not None:
|
||||||
|
req.key = canonical_key
|
||||||
|
dist = self.by_key.get(canonical_key)
|
||||||
|
|
||||||
if dist is not None and dist not in req:
|
if dist is not None and dist not in req:
|
||||||
# XXX add more info
|
# XXX add more info
|
||||||
raise VersionConflict(dist, req)
|
raise VersionConflict(dist, req)
|
||||||
|
@ -706,13 +712,16 @@ class WorkingSet:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.by_key[dist.key] = dist
|
self.by_key[dist.key] = dist
|
||||||
|
normalized_name = packaging.utils.canonicalize_name(dist.key)
|
||||||
|
self.normalized_to_canonical_keys[normalized_name] = dist.key
|
||||||
if dist.key not in keys:
|
if dist.key not in keys:
|
||||||
keys.append(dist.key)
|
keys.append(dist.key)
|
||||||
if dist.key not in keys2:
|
if dist.key not in keys2:
|
||||||
keys2.append(dist.key)
|
keys2.append(dist.key)
|
||||||
self._added_new(dist)
|
self._added_new(dist)
|
||||||
|
|
||||||
def resolve(self, requirements, env=None, installer=None,
|
# FIXME: 'WorkingSet.resolve' is too complex (11)
|
||||||
|
def resolve(self, requirements, env=None, installer=None, # noqa: C901
|
||||||
replace_conflicting=False, extras=None):
|
replace_conflicting=False, extras=None):
|
||||||
"""List all distributions needed to (recursively) meet `requirements`
|
"""List all distributions needed to (recursively) meet `requirements`
|
||||||
|
|
||||||
|
@ -925,14 +934,15 @@ class WorkingSet:
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return (
|
return (
|
||||||
self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
|
self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
|
||||||
self.callbacks[:]
|
self.normalized_to_canonical_keys.copy(), self.callbacks[:]
|
||||||
)
|
)
|
||||||
|
|
||||||
def __setstate__(self, e_k_b_c):
|
def __setstate__(self, e_k_b_n_c):
|
||||||
entries, keys, by_key, callbacks = e_k_b_c
|
entries, keys, by_key, normalized_to_canonical_keys, callbacks = e_k_b_n_c
|
||||||
self.entries = entries[:]
|
self.entries = entries[:]
|
||||||
self.entry_keys = keys.copy()
|
self.entry_keys = keys.copy()
|
||||||
self.by_key = by_key.copy()
|
self.by_key = by_key.copy()
|
||||||
|
self.normalized_to_canonical_keys = normalized_to_canonical_keys.copy()
|
||||||
self.callbacks = callbacks[:]
|
self.callbacks = callbacks[:]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1234,12 +1244,13 @@ class ResourceManager:
|
||||||
mode = os.stat(path).st_mode
|
mode = os.stat(path).st_mode
|
||||||
if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
|
if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
|
||||||
msg = (
|
msg = (
|
||||||
"%s is writable by group/others and vulnerable to attack "
|
"Extraction path is writable by group/others "
|
||||||
"when "
|
"and vulnerable to attack when "
|
||||||
"used with get_resource_filename. Consider a more secure "
|
"used with get_resource_filename ({path}). "
|
||||||
|
"Consider a more secure "
|
||||||
"location (set with .set_extraction_path or the "
|
"location (set with .set_extraction_path or the "
|
||||||
"PYTHON_EGG_CACHE environment variable)." % path
|
"PYTHON_EGG_CACHE environment variable)."
|
||||||
)
|
).format(**locals())
|
||||||
warnings.warn(msg, UserWarning)
|
warnings.warn(msg, UserWarning)
|
||||||
|
|
||||||
def postprocess(self, tempname, filename):
|
def postprocess(self, tempname, filename):
|
||||||
|
@ -1377,7 +1388,7 @@ def evaluate_marker(text, extra=None):
|
||||||
marker = packaging.markers.Marker(text)
|
marker = packaging.markers.Marker(text)
|
||||||
return marker.evaluate()
|
return marker.evaluate()
|
||||||
except packaging.markers.InvalidMarker as e:
|
except packaging.markers.InvalidMarker as e:
|
||||||
raise SyntaxError(e)
|
raise SyntaxError(e) from e
|
||||||
|
|
||||||
|
|
||||||
class NullProvider:
|
class NullProvider:
|
||||||
|
@ -1418,8 +1429,6 @@ class NullProvider:
|
||||||
return ""
|
return ""
|
||||||
path = self._get_metadata_path(name)
|
path = self._get_metadata_path(name)
|
||||||
value = self._get(path)
|
value = self._get(path)
|
||||||
if six.PY2:
|
|
||||||
return value
|
|
||||||
try:
|
try:
|
||||||
return value.decode('utf-8')
|
return value.decode('utf-8')
|
||||||
except UnicodeDecodeError as exc:
|
except UnicodeDecodeError as exc:
|
||||||
|
@ -1457,7 +1466,8 @@ class NullProvider:
|
||||||
script_filename = self._fn(self.egg_info, script)
|
script_filename = self._fn(self.egg_info, script)
|
||||||
namespace['__file__'] = script_filename
|
namespace['__file__'] = script_filename
|
||||||
if os.path.exists(script_filename):
|
if os.path.exists(script_filename):
|
||||||
source = open(script_filename).read()
|
with open(script_filename) as fid:
|
||||||
|
source = fid.read()
|
||||||
code = compile(source, script_filename, 'exec')
|
code = compile(source, script_filename, 'exec')
|
||||||
exec(code, namespace, namespace)
|
exec(code, namespace, namespace)
|
||||||
else:
|
else:
|
||||||
|
@ -1493,7 +1503,7 @@ class NullProvider:
|
||||||
def _validate_resource_path(path):
|
def _validate_resource_path(path):
|
||||||
"""
|
"""
|
||||||
Validate the resource paths according to the docs.
|
Validate the resource paths according to the docs.
|
||||||
https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access
|
https://setuptools.pypa.io/en/latest/pkg_resources.html#basic-resource-access
|
||||||
|
|
||||||
>>> warned = getfixture('recwarn')
|
>>> warned = getfixture('recwarn')
|
||||||
>>> warnings.simplefilter('always')
|
>>> warnings.simplefilter('always')
|
||||||
|
@ -1575,26 +1585,35 @@ is not allowed.
|
||||||
register_loader_type(object, NullProvider)
|
register_loader_type(object, NullProvider)
|
||||||
|
|
||||||
|
|
||||||
|
def _parents(path):
|
||||||
|
"""
|
||||||
|
yield all parents of path including path
|
||||||
|
"""
|
||||||
|
last = None
|
||||||
|
while path != last:
|
||||||
|
yield path
|
||||||
|
last = path
|
||||||
|
path, _ = os.path.split(path)
|
||||||
|
|
||||||
|
|
||||||
class EggProvider(NullProvider):
|
class EggProvider(NullProvider):
|
||||||
"""Provider based on a virtual filesystem"""
|
"""Provider based on a virtual filesystem"""
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
NullProvider.__init__(self, module)
|
super().__init__(module)
|
||||||
self._setup_prefix()
|
self._setup_prefix()
|
||||||
|
|
||||||
def _setup_prefix(self):
|
def _setup_prefix(self):
|
||||||
# we assume here that our metadata may be nested inside a "basket"
|
# Assume that metadata may be nested inside a "basket"
|
||||||
# of multiple eggs; that's why we use module_path instead of .archive
|
# of multiple eggs and use module_path instead of .archive.
|
||||||
path = self.module_path
|
eggs = filter(_is_egg_path, _parents(self.module_path))
|
||||||
old = None
|
egg = next(eggs, None)
|
||||||
while path != old:
|
egg and self._set_egg(egg)
|
||||||
if _is_egg_path(path):
|
|
||||||
self.egg_name = os.path.basename(path)
|
def _set_egg(self, path):
|
||||||
self.egg_info = os.path.join(path, 'EGG-INFO')
|
self.egg_name = os.path.basename(path)
|
||||||
self.egg_root = path
|
self.egg_info = os.path.join(path, 'EGG-INFO')
|
||||||
break
|
self.egg_root = path
|
||||||
old = path
|
|
||||||
path, base = os.path.split(path)
|
|
||||||
|
|
||||||
|
|
||||||
class DefaultProvider(EggProvider):
|
class DefaultProvider(EggProvider):
|
||||||
|
@ -1701,7 +1720,7 @@ class ZipProvider(EggProvider):
|
||||||
_zip_manifests = MemoizedZipManifests()
|
_zip_manifests = MemoizedZipManifests()
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
EggProvider.__init__(self, module)
|
super().__init__(module)
|
||||||
self.zip_pre = self.loader.archive + os.sep
|
self.zip_pre = self.loader.archive + os.sep
|
||||||
|
|
||||||
def _zipinfo_name(self, fspath):
|
def _zipinfo_name(self, fspath):
|
||||||
|
@ -1752,7 +1771,8 @@ class ZipProvider(EggProvider):
|
||||||
timestamp = time.mktime(date_time)
|
timestamp = time.mktime(date_time)
|
||||||
return timestamp, size
|
return timestamp, size
|
||||||
|
|
||||||
def _extract_resource(self, manager, zip_path):
|
# FIXME: 'ZipProvider._extract_resource' is too complex (12)
|
||||||
|
def _extract_resource(self, manager, zip_path): # noqa: C901
|
||||||
|
|
||||||
if zip_path in self._index():
|
if zip_path in self._index():
|
||||||
for name in self._index()[zip_path]:
|
for name in self._index()[zip_path]:
|
||||||
|
@ -1900,8 +1920,7 @@ class FileMetadata(EmptyProvider):
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def _warn_on_replacement(self, metadata):
|
def _warn_on_replacement(self, metadata):
|
||||||
# Python 2.7 compat for: replacement_char = '<27>'
|
replacement_char = '<EFBFBD>'
|
||||||
replacement_char = b'\xef\xbf\xbd'.decode('utf-8')
|
|
||||||
if replacement_char in metadata:
|
if replacement_char in metadata:
|
||||||
tmpl = "{self.path} could not be properly decoded in UTF-8"
|
tmpl = "{self.path} could not be properly decoded in UTF-8"
|
||||||
msg = tmpl.format(**locals())
|
msg = tmpl.format(**locals())
|
||||||
|
@ -1991,7 +2010,7 @@ def find_eggs_in_zip(importer, path_item, only=False):
|
||||||
dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
|
dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
|
||||||
for dist in dists:
|
for dist in dists:
|
||||||
yield dist
|
yield dist
|
||||||
elif subitem.lower().endswith('.dist-info'):
|
elif subitem.lower().endswith(('.dist-info', '.egg-info')):
|
||||||
subpath = os.path.join(path_item, subitem)
|
subpath = os.path.join(path_item, subitem)
|
||||||
submeta = EggMetadata(zipimport.zipimporter(subpath))
|
submeta = EggMetadata(zipimport.zipimporter(subpath))
|
||||||
submeta.egg_info = subpath
|
submeta.egg_info = subpath
|
||||||
|
@ -2015,7 +2034,7 @@ def _by_version_descending(names):
|
||||||
|
|
||||||
>>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
|
>>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
|
||||||
>>> _by_version_descending(names)
|
>>> _by_version_descending(names)
|
||||||
['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar']
|
['Python-2.7.10.egg', 'Python-2.7.2.egg', 'bar', 'foo']
|
||||||
>>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
|
>>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
|
||||||
>>> _by_version_descending(names)
|
>>> _by_version_descending(names)
|
||||||
['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
|
['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
|
||||||
|
@ -2023,13 +2042,22 @@ def _by_version_descending(names):
|
||||||
>>> _by_version_descending(names)
|
>>> _by_version_descending(names)
|
||||||
['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
|
['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
|
||||||
"""
|
"""
|
||||||
|
def try_parse(name):
|
||||||
|
"""
|
||||||
|
Attempt to parse as a version or return a null version.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return packaging.version.Version(name)
|
||||||
|
except Exception:
|
||||||
|
return packaging.version.Version('0')
|
||||||
|
|
||||||
def _by_version(name):
|
def _by_version(name):
|
||||||
"""
|
"""
|
||||||
Parse each component of the filename
|
Parse each component of the filename
|
||||||
"""
|
"""
|
||||||
name, ext = os.path.splitext(name)
|
name, ext = os.path.splitext(name)
|
||||||
parts = itertools.chain(name.split('-'), [ext])
|
parts = itertools.chain(name.split('-'), [ext])
|
||||||
return [packaging.version.parse(part) for part in parts]
|
return [try_parse(part) for part in parts]
|
||||||
|
|
||||||
return sorted(names, key=_by_version, reverse=True)
|
return sorted(names, key=_by_version, reverse=True)
|
||||||
|
|
||||||
|
@ -2046,7 +2074,10 @@ def find_on_path(importer, path_item, only=False):
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
entries = safe_listdir(path_item)
|
entries = (
|
||||||
|
os.path.join(path_item, child)
|
||||||
|
for child in safe_listdir(path_item)
|
||||||
|
)
|
||||||
|
|
||||||
# for performance, before sorting by version,
|
# for performance, before sorting by version,
|
||||||
# screen entries for only those that will yield
|
# screen entries for only those that will yield
|
||||||
|
@ -2067,11 +2098,14 @@ def find_on_path(importer, path_item, only=False):
|
||||||
|
|
||||||
|
|
||||||
def dist_factory(path_item, entry, only):
|
def dist_factory(path_item, entry, only):
|
||||||
"""
|
"""Return a dist_factory for the given entry."""
|
||||||
Return a dist_factory for a path_item and entry
|
|
||||||
"""
|
|
||||||
lower = entry.lower()
|
lower = entry.lower()
|
||||||
is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info')))
|
is_egg_info = lower.endswith('.egg-info')
|
||||||
|
is_dist_info = (
|
||||||
|
lower.endswith('.dist-info') and
|
||||||
|
os.path.isdir(os.path.join(path_item, entry))
|
||||||
|
)
|
||||||
|
is_meta = is_egg_info or is_dist_info
|
||||||
return (
|
return (
|
||||||
distributions_from_metadata
|
distributions_from_metadata
|
||||||
if is_meta else
|
if is_meta else
|
||||||
|
@ -2093,8 +2127,6 @@ class NoDists:
|
||||||
"""
|
"""
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return False
|
return False
|
||||||
if six.PY2:
|
|
||||||
__nonzero__ = __bool__
|
|
||||||
|
|
||||||
def __call__(self, fullpath):
|
def __call__(self, fullpath):
|
||||||
return iter(())
|
return iter(())
|
||||||
|
@ -2111,12 +2143,7 @@ def safe_listdir(path):
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
# Ignore the directory if does not exist, not a directory or
|
# Ignore the directory if does not exist, not a directory or
|
||||||
# permission denied
|
# permission denied
|
||||||
ignorable = (
|
if e.errno not in (errno.ENOTDIR, errno.EACCES, errno.ENOENT):
|
||||||
e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT)
|
|
||||||
# Python 2 on Windows needs to be handled this way :(
|
|
||||||
or getattr(e, "winerror", None) == 267
|
|
||||||
)
|
|
||||||
if not ignorable:
|
|
||||||
raise
|
raise
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
@ -2195,10 +2222,16 @@ def _handle_ns(packageName, path_item):
|
||||||
if importer is None:
|
if importer is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# capture warnings due to #1111
|
# use find_spec (PEP 451) and fall-back to find_module (PEP 302)
|
||||||
with warnings.catch_warnings():
|
try:
|
||||||
warnings.simplefilter("ignore")
|
spec = importer.find_spec(packageName)
|
||||||
loader = importer.find_module(packageName)
|
except AttributeError:
|
||||||
|
# capture warnings due to #1111
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.simplefilter("ignore")
|
||||||
|
loader = importer.find_module(packageName)
|
||||||
|
else:
|
||||||
|
loader = spec.loader if spec else None
|
||||||
|
|
||||||
if loader is None:
|
if loader is None:
|
||||||
return None
|
return None
|
||||||
|
@ -2214,7 +2247,7 @@ def _handle_ns(packageName, path_item):
|
||||||
if subpath is not None:
|
if subpath is not None:
|
||||||
path = module.__path__
|
path = module.__path__
|
||||||
path.append(subpath)
|
path.append(subpath)
|
||||||
loader.load_module(packageName)
|
importlib.import_module(packageName)
|
||||||
_rebuild_mod_path(path, packageName, module)
|
_rebuild_mod_path(path, packageName, module)
|
||||||
return subpath
|
return subpath
|
||||||
|
|
||||||
|
@ -2270,8 +2303,8 @@ def declare_namespace(packageName):
|
||||||
__import__(parent)
|
__import__(parent)
|
||||||
try:
|
try:
|
||||||
path = sys.modules[parent].__path__
|
path = sys.modules[parent].__path__
|
||||||
except AttributeError:
|
except AttributeError as e:
|
||||||
raise TypeError("Not a package:", parent)
|
raise TypeError("Not a package:", parent) from e
|
||||||
|
|
||||||
# Track what packages are namespaces, so when new path items are added,
|
# Track what packages are namespaces, so when new path items are added,
|
||||||
# they can be updated
|
# they can be updated
|
||||||
|
@ -2328,7 +2361,8 @@ register_namespace_handler(object, null_ns_handler)
|
||||||
|
|
||||||
def normalize_path(filename):
|
def normalize_path(filename):
|
||||||
"""Normalize a file/dir name for comparison purposes"""
|
"""Normalize a file/dir name for comparison purposes"""
|
||||||
return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename))))
|
return os.path.normcase(os.path.realpath(os.path.normpath(
|
||||||
|
_cygwin_patch(filename))))
|
||||||
|
|
||||||
|
|
||||||
def _cygwin_patch(filename): # pragma: nocover
|
def _cygwin_patch(filename): # pragma: nocover
|
||||||
|
@ -2354,7 +2388,15 @@ def _is_egg_path(path):
|
||||||
"""
|
"""
|
||||||
Determine if given path appears to be an egg.
|
Determine if given path appears to be an egg.
|
||||||
"""
|
"""
|
||||||
return path.lower().endswith('.egg')
|
return _is_zip_egg(path) or _is_unpacked_egg(path)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_zip_egg(path):
|
||||||
|
return (
|
||||||
|
path.lower().endswith('.egg') and
|
||||||
|
os.path.isfile(path) and
|
||||||
|
zipfile.is_zipfile(path)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _is_unpacked_egg(path):
|
def _is_unpacked_egg(path):
|
||||||
|
@ -2362,7 +2404,7 @@ def _is_unpacked_egg(path):
|
||||||
Determine if given path appears to be an unpacked egg.
|
Determine if given path appears to be an unpacked egg.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
_is_egg_path(path) and
|
path.lower().endswith('.egg') and
|
||||||
os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO'))
|
os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2375,20 +2417,6 @@ def _set_parent_ns(packageName):
|
||||||
setattr(sys.modules[parent], name, sys.modules[packageName])
|
setattr(sys.modules[parent], name, sys.modules[packageName])
|
||||||
|
|
||||||
|
|
||||||
def yield_lines(strs):
|
|
||||||
"""Yield non-empty/non-comment lines of a string or sequence"""
|
|
||||||
if isinstance(strs, six.string_types):
|
|
||||||
for s in strs.splitlines():
|
|
||||||
s = s.strip()
|
|
||||||
# skip blank lines/comments
|
|
||||||
if s and not s.startswith('#'):
|
|
||||||
yield s
|
|
||||||
else:
|
|
||||||
for ss in strs:
|
|
||||||
for s in yield_lines(ss):
|
|
||||||
yield s
|
|
||||||
|
|
||||||
|
|
||||||
MODULE = re.compile(r"\w+(\.\w+)*$").match
|
MODULE = re.compile(r"\w+(\.\w+)*$").match
|
||||||
EGG_NAME = re.compile(
|
EGG_NAME = re.compile(
|
||||||
r"""
|
r"""
|
||||||
|
@ -2450,7 +2478,7 @@ class EntryPoint:
|
||||||
try:
|
try:
|
||||||
return functools.reduce(getattr, self.attrs, module)
|
return functools.reduce(getattr, self.attrs, module)
|
||||||
except AttributeError as exc:
|
except AttributeError as exc:
|
||||||
raise ImportError(str(exc))
|
raise ImportError(str(exc)) from exc
|
||||||
|
|
||||||
def require(self, env=None, installer=None):
|
def require(self, env=None, installer=None):
|
||||||
if self.extras and not self.dist:
|
if self.extras and not self.dist:
|
||||||
|
@ -2536,15 +2564,6 @@ class EntryPoint:
|
||||||
return maps
|
return maps
|
||||||
|
|
||||||
|
|
||||||
def _remove_md5_fragment(location):
|
|
||||||
if not location:
|
|
||||||
return ''
|
|
||||||
parsed = urllib.parse.urlparse(location)
|
|
||||||
if parsed[-1].startswith('md5='):
|
|
||||||
return urllib.parse.urlunparse(parsed[:-1] + ('',))
|
|
||||||
return location
|
|
||||||
|
|
||||||
|
|
||||||
def _version_from_file(lines):
|
def _version_from_file(lines):
|
||||||
"""
|
"""
|
||||||
Given an iterable of lines from a Metadata file, return
|
Given an iterable of lines from a Metadata file, return
|
||||||
|
@ -2601,7 +2620,7 @@ class Distribution:
|
||||||
self.parsed_version,
|
self.parsed_version,
|
||||||
self.precedence,
|
self.precedence,
|
||||||
self.key,
|
self.key,
|
||||||
_remove_md5_fragment(self.location),
|
self.location,
|
||||||
self.py_version or '',
|
self.py_version or '',
|
||||||
self.platform or '',
|
self.platform or '',
|
||||||
)
|
)
|
||||||
|
@ -2679,14 +2698,14 @@ class Distribution:
|
||||||
def version(self):
|
def version(self):
|
||||||
try:
|
try:
|
||||||
return self._version
|
return self._version
|
||||||
except AttributeError:
|
except AttributeError as e:
|
||||||
version = self._get_version()
|
version = self._get_version()
|
||||||
if version is None:
|
if version is None:
|
||||||
path = self._get_metadata_path_for_display(self.PKG_INFO)
|
path = self._get_metadata_path_for_display(self.PKG_INFO)
|
||||||
msg = (
|
msg = (
|
||||||
"Missing 'Version:' header and/or {} file at path: {}"
|
"Missing 'Version:' header and/or {} file at path: {}"
|
||||||
).format(self.PKG_INFO, path)
|
).format(self.PKG_INFO, path)
|
||||||
raise ValueError(msg, self)
|
raise ValueError(msg, self) from e
|
||||||
|
|
||||||
return version
|
return version
|
||||||
|
|
||||||
|
@ -2739,10 +2758,10 @@ class Distribution:
|
||||||
for ext in extras:
|
for ext in extras:
|
||||||
try:
|
try:
|
||||||
deps.extend(dm[safe_extra(ext)])
|
deps.extend(dm[safe_extra(ext)])
|
||||||
except KeyError:
|
except KeyError as e:
|
||||||
raise UnknownExtra(
|
raise UnknownExtra(
|
||||||
"%s has no such extra feature %r" % (self, ext)
|
"%s has no such extra feature %r" % (self, ext)
|
||||||
)
|
) from e
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
def _get_metadata_path_for_display(self, name):
|
def _get_metadata_path_for_display(self, name):
|
||||||
|
@ -2824,10 +2843,6 @@ class Distribution:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not hasattr(object, '__dir__'):
|
|
||||||
# python 2.7 not supported
|
|
||||||
del __dir__
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_filename(cls, filename, metadata=None, **kw):
|
def from_filename(cls, filename, metadata=None, **kw):
|
||||||
return cls.from_location(
|
return cls.from_location(
|
||||||
|
@ -2867,7 +2882,8 @@ class Distribution:
|
||||||
"""Return the EntryPoint object for `group`+`name`, or ``None``"""
|
"""Return the EntryPoint object for `group`+`name`, or ``None``"""
|
||||||
return self.get_entry_map(group).get(name)
|
return self.get_entry_map(group).get(name)
|
||||||
|
|
||||||
def insert_on(self, path, loc=None, replace=False):
|
# FIXME: 'Distribution.insert_on' is too complex (13)
|
||||||
|
def insert_on(self, path, loc=None, replace=False): # noqa: C901
|
||||||
"""Ensure self.location is on path
|
"""Ensure self.location is on path
|
||||||
|
|
||||||
If replace=False (default):
|
If replace=False (default):
|
||||||
|
@ -3037,12 +3053,12 @@ class DistInfoDistribution(Distribution):
|
||||||
if not req.marker or req.marker.evaluate({'extra': extra}):
|
if not req.marker or req.marker.evaluate({'extra': extra}):
|
||||||
yield req
|
yield req
|
||||||
|
|
||||||
common = frozenset(reqs_for_extra(None))
|
common = types.MappingProxyType(dict.fromkeys(reqs_for_extra(None)))
|
||||||
dm[None].extend(common)
|
dm[None].extend(common)
|
||||||
|
|
||||||
for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
|
for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
|
||||||
s_extra = safe_extra(extra.strip())
|
s_extra = safe_extra(extra.strip())
|
||||||
dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common)
|
dm[s_extra] = [r for r in reqs_for_extra(extra) if r not in common]
|
||||||
|
|
||||||
return dm
|
return dm
|
||||||
|
|
||||||
|
@ -3067,40 +3083,23 @@ def issue_warning(*args, **kw):
|
||||||
warnings.warn(stacklevel=level + 1, *args, **kw)
|
warnings.warn(stacklevel=level + 1, *args, **kw)
|
||||||
|
|
||||||
|
|
||||||
class RequirementParseError(ValueError):
|
|
||||||
def __str__(self):
|
|
||||||
return ' '.join(self.args)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_requirements(strs):
|
def parse_requirements(strs):
|
||||||
"""Yield ``Requirement`` objects for each specification in `strs`
|
"""
|
||||||
|
Yield ``Requirement`` objects for each specification in `strs`.
|
||||||
|
|
||||||
`strs` must be a string, or a (possibly-nested) iterable thereof.
|
`strs` must be a string, or a (possibly-nested) iterable thereof.
|
||||||
"""
|
"""
|
||||||
# create a steppable iterator, so we can handle \-continuations
|
return map(Requirement, join_continuation(map(drop_comment, yield_lines(strs))))
|
||||||
lines = iter(yield_lines(strs))
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
# Drop comments -- a hash without a space may be in a URL.
|
class RequirementParseError(packaging.requirements.InvalidRequirement):
|
||||||
if ' #' in line:
|
"Compatibility wrapper for InvalidRequirement"
|
||||||
line = line[:line.find(' #')]
|
|
||||||
# If there is a line continuation, drop it, and append the next line.
|
|
||||||
if line.endswith('\\'):
|
|
||||||
line = line[:-2].strip()
|
|
||||||
try:
|
|
||||||
line += next(lines)
|
|
||||||
except StopIteration:
|
|
||||||
return
|
|
||||||
yield Requirement(line)
|
|
||||||
|
|
||||||
|
|
||||||
class Requirement(packaging.requirements.Requirement):
|
class Requirement(packaging.requirements.Requirement):
|
||||||
def __init__(self, requirement_string):
|
def __init__(self, requirement_string):
|
||||||
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
|
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
|
||||||
try:
|
super(Requirement, self).__init__(requirement_string)
|
||||||
super(Requirement, self).__init__(requirement_string)
|
|
||||||
except packaging.requirements.InvalidRequirement as e:
|
|
||||||
raise RequirementParseError(str(e))
|
|
||||||
self.unsafe_name = self.name
|
self.unsafe_name = self.name
|
||||||
project_name = safe_name(self.name)
|
project_name = safe_name(self.name)
|
||||||
self.project_name, self.key = project_name, project_name.lower()
|
self.project_name, self.key = project_name, project_name.lower()
|
||||||
|
@ -3170,7 +3169,7 @@ def _find_adapter(registry, ob):
|
||||||
def ensure_directory(path):
|
def ensure_directory(path):
|
||||||
"""Ensure that the parent directory of `path` exists"""
|
"""Ensure that the parent directory of `path` exists"""
|
||||||
dirname = os.path.dirname(path)
|
dirname = os.path.dirname(path)
|
||||||
py31compat.makedirs(dirname, exist_ok=True)
|
os.makedirs(dirname, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
def _bypass_ensure_directory(path):
|
def _bypass_ensure_directory(path):
|
||||||
|
@ -3248,6 +3247,15 @@ def _initialize(g=globals()):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PkgResourcesDeprecationWarning(Warning):
|
||||||
|
"""
|
||||||
|
Base class for warning about deprecations in ``pkg_resources``
|
||||||
|
|
||||||
|
This class is not derived from ``DeprecationWarning``, and as such is
|
||||||
|
visible by default.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@_call_aside
|
@_call_aside
|
||||||
def _initialize_master_working_set():
|
def _initialize_master_working_set():
|
||||||
"""
|
"""
|
||||||
|
@ -3286,11 +3294,3 @@ def _initialize_master_working_set():
|
||||||
# match order
|
# match order
|
||||||
list(map(working_set.add_entry, sys.path))
|
list(map(working_set.add_entry, sys.path))
|
||||||
globals().update(locals())
|
globals().update(locals())
|
||||||
|
|
||||||
class PkgResourcesDeprecationWarning(Warning):
|
|
||||||
"""
|
|
||||||
Base class for warning about deprecations in ``pkg_resources``
|
|
||||||
|
|
||||||
This class is not derived from ``DeprecationWarning``, and as such is
|
|
||||||
visible by default.
|
|
||||||
"""
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import os
|
|
||||||
import errno
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from pip._vendor import six
|
|
||||||
|
|
||||||
|
|
||||||
def _makedirs_31(path, exist_ok=False):
|
|
||||||
try:
|
|
||||||
os.makedirs(path)
|
|
||||||
except OSError as exc:
|
|
||||||
if not exist_ok or exc.errno != errno.EEXIST:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
# rely on compatibility behavior until mode considerations
|
|
||||||
# and exists_ok considerations are disentangled.
|
|
||||||
# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663
|
|
||||||
needs_makedirs = (
|
|
||||||
six.PY2 or
|
|
||||||
(3, 4) <= sys.version_info < (3, 4, 1)
|
|
||||||
)
|
|
||||||
makedirs = _makedirs_31 if needs_makedirs else os.makedirs
|
|
|
@ -16,7 +16,7 @@ rich==12.6.0
|
||||||
pygments==2.13.0
|
pygments==2.13.0
|
||||||
typing_extensions==4.4.0
|
typing_extensions==4.4.0
|
||||||
resolvelib==0.8.1
|
resolvelib==0.8.1
|
||||||
setuptools==44.0.0
|
setuptools==65.6.3
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
tenacity==8.1.0
|
tenacity==8.1.0
|
||||||
tomli==2.0.1
|
tomli==2.0.1
|
||||||
|
|
|
@ -1,22 +1,35 @@
|
||||||
diff --git a/src/pip/_vendor/pkg_resources/__init__.py b/src/pip/_vendor/pkg_resources/__init__.py
|
diff --git a/src/pip/_vendor/pkg_resources/__init__.py b/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
index a457ff27e..4cd562cf9 100644
|
index d59226af9..3b9565893 100644
|
||||||
--- a/src/pip/_vendor/pkg_resources/__init__.py
|
--- a/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
+++ b/src/pip/_vendor/pkg_resources/__init__.py
|
+++ b/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
@@ -77,7 +77,7 @@ except ImportError:
|
@@ -77,7 +77,7 @@
|
||||||
importlib_machinery = None
|
join_continuation,
|
||||||
|
)
|
||||||
|
|
||||||
from . import py31compat
|
|
||||||
-from pkg_resources.extern import appdirs
|
-from pkg_resources.extern import appdirs
|
||||||
+from pkg_resources.extern import platformdirs
|
+from pkg_resources.extern import platformdirs
|
||||||
from pkg_resources.extern import packaging
|
from pkg_resources.extern import packaging
|
||||||
__import__('pkg_resources.extern.packaging.version')
|
__import__('pkg_resources.extern.packaging.version')
|
||||||
__import__('pkg_resources.extern.packaging.specifiers')
|
__import__('pkg_resources.extern.packaging.specifiers')
|
||||||
@@ -1310,7 +1310,7 @@ def get_default_cache():
|
@@ -1321,7 +1321,7 @@ def get_default_cache():
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
os.environ.get('PYTHON_EGG_CACHE')
|
os.environ.get('PYTHON_EGG_CACHE')
|
||||||
- or appdirs.user_cache_dir(appname='Python-Eggs')
|
- or appdirs.user_cache_dir(appname='Python-Eggs')
|
||||||
+ or platformdirs.user_cache_dir(appname='Python-Eggs')
|
+ or platformdirs.user_cache_dir(appname='Python-Eggs')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/pip/_vendor/pkg_resources/__init__.py b/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
|
index 3f2476a0c..8d5727d35 100644
|
||||||
|
--- a/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
|
+++ b/src/pip/_vendor/pkg_resources/__init__.py
|
||||||
|
@@ -71,7 +71,7 @@
|
||||||
|
except ImportError:
|
||||||
|
importlib_machinery = None
|
||||||
|
|
||||||
|
-from pkg_resources.extern.jaraco.text import (
|
||||||
|
+from pip._internal.utils._jaraco_text import (
|
||||||
|
yield_lines,
|
||||||
|
drop_comment,
|
||||||
|
join_continuation,
|
||||||
|
|
Loading…
Reference in New Issue