Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade distlib to 0.3.7 #12359

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/distlib.vendor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upgrade distlib to 0.3.7
2 changes: 1 addition & 1 deletion src/pip/_vendor/distlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
import logging

__version__ = '0.3.6'
__version__ = '0.3.7'

class DistlibException(Exception):
pass
Expand Down
9 changes: 6 additions & 3 deletions src/pip/_vendor/distlib/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,15 +903,18 @@ def parse_requires_data(data):
lines = data.splitlines()
for line in lines:
line = line.strip()
if line.startswith('['):
# sectioned files have bare newlines (separating sections)
if not line: # pragma: no cover
continue
if line.startswith('['): # pragma: no cover
logger.warning('Unexpected line: quitting requirement scan: %r',
line)
break
r = parse_requirement(line)
if not r:
if not r: # pragma: no cover
logger.warning('Not recognised as a requirement: %r', line)
continue
if r.extras:
if r.extras: # pragma: no cover
logger.warning('extra requirements in requires.txt are '
'not supported')
if not r.constraints:
Expand Down
5 changes: 3 additions & 2 deletions src/pip/_vendor/distlib/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
_PYTHON_VERSION = sys.version_info[:2]

class Manifest(object):
"""A list of files built by on exploring the filesystem and filtered by
applying various patterns to what we find there.
"""
A list of files built by exploring the filesystem and filtered by applying various
patterns to what we find there.
"""

def __init__(self, base=None):
Expand Down
15 changes: 8 additions & 7 deletions src/pip/_vendor/distlib/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@
__all__ = ['interpret']

_VERSION_PATTERN = re.compile(r'((\d+(\.\d+)*\w*)|\'(\d+(\.\d+)*\w*)\'|\"(\d+(\.\d+)*\w*)\")')
_VERSION_MARKERS = {'python_version', 'python_full_version'}

def _is_version_marker(s):
return isinstance(s, string_types) and s in _VERSION_MARKERS

def _is_literal(o):
if not isinstance(o, string_types) or not o:
return False
return o[0] in '\'"'

def _get_versions(s):
result = []
for m in _VERSION_PATTERN.finditer(s):
result.append(NV(m.groups()[0]))
return set(result)
return {NV(m.groups()[0]) for m in _VERSION_PATTERN.finditer(s)}

class Evaluator(object):
"""
This class is used to evaluate marker expessions.
This class is used to evaluate marker expressions.
"""

operations = {
Expand Down Expand Up @@ -80,11 +81,11 @@ def evaluate(self, expr, context):

lhs = self.evaluate(elhs, context)
rhs = self.evaluate(erhs, context)
if ((elhs == 'python_version' or erhs == 'python_version') and
if ((_is_version_marker(elhs) or _is_version_marker(erhs)) and
op in ('<', '<=', '>', '>=', '===', '==', '!=', '~=')):
lhs = NV(lhs)
rhs = NV(rhs)
elif elhs == 'python_version' and op in ('in', 'not in'):
elif _is_version_marker(elhs) and op in ('in', 'not in'):
lhs = NV(lhs)
rhs = _get_versions(rhs)
result = self.operations[op](lhs, rhs)
Expand Down
12 changes: 2 additions & 10 deletions src/pip/_vendor/distlib/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,9 @@ def _version2fieldlist(version):
def _best_version(fields):
"""Detect the best version depending on the fields used."""
def _has_marker(keys, markers):
for marker in markers:
if marker in keys:
return True
return False

keys = []
for key, value in fields.items():
if value in ([], 'UNKNOWN', None):
continue
keys.append(key)
return any(marker in keys for marker in markers)

keys = [key for key, value in fields.items() if value not in ([], 'UNKNOWN', None)]
possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.1', '2.2'] # 2.0 removed

# first let's try to see if a field is not part of one of the version
Expand Down
11 changes: 6 additions & 5 deletions src/pip/_vendor/distlib/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,16 @@ def _get_shebang(self, encoding, post_interp=b'', options=None):
executable = os.path.join(sysconfig.get_path('scripts'),
'python%s' % sysconfig.get_config_var('EXE'))
else: # pragma: no cover
executable = os.path.join(
sysconfig.get_config_var('BINDIR'),
'python%s%s' % (sysconfig.get_config_var('VERSION'),
sysconfig.get_config_var('EXE')))
if not os.path.isfile(executable):
if os.name == 'nt':
# for Python builds from source on Windows, no Python executables with
# a version suffix are created, so we use python.exe
executable = os.path.join(sysconfig.get_config_var('BINDIR'),
'python%s' % (sysconfig.get_config_var('EXE')))
else:
executable = os.path.join(
sysconfig.get_config_var('BINDIR'),
'python%s%s' % (sysconfig.get_config_var('VERSION'),
sysconfig.get_config_var('EXE')))
if options:
executable = self._get_alternate_executable(executable, options)

Expand Down
25 changes: 21 additions & 4 deletions src/pip/_vendor/distlib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ def __eq__(self, other):
__hash__ = object.__hash__


ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+)
ENTRY_RE = re.compile(r'''(?P<name>([^\[]\S*))
\s*=\s*(?P<callable>(\w+)([:\.]\w+)*)
\s*(\[\s*(?P<flags>[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])?
''', re.VERBOSE)
Expand Down Expand Up @@ -1249,6 +1249,19 @@ def check_path(path):
for tarinfo in archive.getmembers():
if not isinstance(tarinfo.name, text_type):
tarinfo.name = tarinfo.name.decode('utf-8')

# Limit extraction of dangerous items, if this Python
# allows it easily. If not, just trust the input.
# See: https://docs.python.org/3/library/tarfile.html#extraction-filters
def extraction_filter(member, path):
"""Run tarfile.tar_filter, but raise the expected ValueError"""
# This is only called if the current Python has tarfile filters
try:
return tarfile.tar_filter(member, path)
except tarfile.FilterError as exc:
raise ValueError(str(exc))
archive.extraction_filter = extraction_filter

archive.extractall(dest_dir)

finally:
Expand Down Expand Up @@ -1435,7 +1448,7 @@ def connect(self):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
if hasattr(ssl, 'OP_NO_SSLv2'):
context.options |= ssl.OP_NO_SSLv2
if self.cert_file:
if getattr(self, 'cert_file', None):
context.load_cert_chain(self.cert_file, self.key_file)
kwargs = {}
if self.ca_certs:
Expand Down Expand Up @@ -1908,9 +1921,13 @@ def get_host_platform():
if m:
release = m.group()
elif osname[:6] == 'darwin':
import _osx_support, distutils.sysconfig
import _osx_support
try:
from distutils import sysconfig
except ImportError:
import sysconfig
osname, release, machine = _osx_support.get_platform_osx(
distutils.sysconfig.get_config_vars(),
sysconfig.get_config_vars(),
osname, release, machine)

return '%s-%s-%s' % (osname, release, machine)
Expand Down
21 changes: 15 additions & 6 deletions src/pip/_vendor/distlib/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ def __str__(self):
return self._string


PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?'
r'(\.(post)(\d+))?(\.(dev)(\d+))?'
r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$')
PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|alpha|b|beta|c|rc|pre|preview)(\d+)?)?'
r'(\.(post|r|rev)(\d+)?)?([._-]?(dev)(\d+)?)?'
r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$', re.I)


def _pep_440_key(s):
Expand All @@ -202,15 +202,24 @@ def _pep_440_key(s):
if pre == (None, None):
pre = ()
else:
pre = pre[0], int(pre[1])
if pre[1] is None:
pre = pre[0], 0
else:
pre = pre[0], int(pre[1])
if post == (None, None):
post = ()
else:
post = post[0], int(post[1])
if post[1] is None:
post = post[0], 0
else:
post = post[0], int(post[1])
if dev == (None, None):
dev = ()
else:
dev = dev[0], int(dev[1])
if dev[1] is None:
dev = dev[0], 0
else:
dev = dev[0], int(dev[1])
if local is None:
local = ()
else:
Expand Down
2 changes: 1 addition & 1 deletion src/pip/_vendor/vendor.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CacheControl==0.13.1 # Make sure to update the license in pyproject.toml for this.
colorama==0.4.6
distlib==0.3.6
distlib==0.3.7
distro==1.8.0
msgpack==1.0.5
packaging==21.3
Expand Down
9 changes: 3 additions & 6 deletions tests/functional/test_uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,9 @@ def test_uninstall_overlapping_package(
"console_scripts",
[
"test_ = distutils_install:test",
pytest.param(
"test_:test_ = distutils_install:test_test",
marks=pytest.mark.xfail(
reason="colon not supported in wheel entry point name?"
),
),
"test_:test_ = distutils_install:test_test",
",test_ = distutils_install:test_test",
", = distutils_install:test_test",
],
)
def test_uninstall_entry_point_colon_in_name(
Expand Down