mirror of https://github.com/pypa/pip
Change PackageFinder to use Tuple[int, ...] instead of List[str] for --python-version.
This commit is contained in:
parent
fada348b00
commit
798d814629
|
@ -324,7 +324,7 @@ class RequirementCommand(Command):
|
|||
options, # type: Values
|
||||
session, # type: PipSession
|
||||
platform=None, # type: Optional[str]
|
||||
python_versions=None, # type: Optional[List[str]]
|
||||
py_version_info=None, # type: Optional[Tuple[int, ...]]
|
||||
abi=None, # type: Optional[str]
|
||||
implementation=None, # type: Optional[str]
|
||||
ignore_requires_python=None, # type: Optional[bool]
|
||||
|
@ -352,7 +352,7 @@ class RequirementCommand(Command):
|
|||
allow_all_prereleases=options.pre,
|
||||
session=session,
|
||||
platform=platform,
|
||||
versions=python_versions,
|
||||
py_version_info=py_version_info,
|
||||
abi=abi,
|
||||
implementation=implementation,
|
||||
prefer_binary=options.prefer_binary,
|
||||
|
|
|
@ -24,7 +24,7 @@ from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
|||
from pip._internal.utils.ui import BAR_TYPES
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Any, Callable, Dict, Optional
|
||||
from typing import Any, Callable, Dict, Optional, Tuple
|
||||
from optparse import OptionParser, Values
|
||||
from pip._internal.cli.parser import ConfigOptionParser
|
||||
|
||||
|
@ -478,11 +478,36 @@ platform = partial(
|
|||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
# This was made a separate function for unit-testing purposes.
|
||||
def _convert_python_version(value):
|
||||
# type: (str) -> Tuple[int, ...]
|
||||
"""
|
||||
Convert a string like "3" or "34" into a tuple of ints.
|
||||
"""
|
||||
if len(value) == 1:
|
||||
parts = [value]
|
||||
else:
|
||||
parts = [value[0], value[1:]]
|
||||
|
||||
return tuple(int(part) for part in parts)
|
||||
|
||||
|
||||
def _handle_python_version(option, opt_str, value, parser):
|
||||
# type: (Option, str, str, OptionParser) -> None
|
||||
"""
|
||||
Convert a string like "3" or "34" into a tuple of ints.
|
||||
"""
|
||||
version_info = _convert_python_version(value)
|
||||
parser.values.python_version = version_info
|
||||
|
||||
|
||||
python_version = partial(
|
||||
Option,
|
||||
'--python-version',
|
||||
dest='python_version',
|
||||
metavar='python_version',
|
||||
action='callback',
|
||||
callback=_handle_python_version, type='str',
|
||||
default=None,
|
||||
help=("Only use wheels compatible with Python "
|
||||
"interpreter version <version>. If not specified, then the "
|
||||
|
|
|
@ -88,11 +88,6 @@ class DownloadCommand(RequirementCommand):
|
|||
# of the RequirementSet code require that property.
|
||||
options.editables = []
|
||||
|
||||
if options.python_version:
|
||||
python_versions = [options.python_version]
|
||||
else:
|
||||
python_versions = None
|
||||
|
||||
cmdoptions.check_dist_restriction(options)
|
||||
|
||||
options.src_dir = os.path.abspath(options.src_dir)
|
||||
|
@ -105,7 +100,7 @@ class DownloadCommand(RequirementCommand):
|
|||
options=options,
|
||||
session=session,
|
||||
platform=options.platform,
|
||||
python_versions=python_versions,
|
||||
py_version_info=options.python_version,
|
||||
abi=options.abi,
|
||||
implementation=options.implementation,
|
||||
)
|
||||
|
|
|
@ -251,11 +251,6 @@ class InstallCommand(RequirementCommand):
|
|||
|
||||
cmdoptions.check_dist_restriction(options, check_target=True)
|
||||
|
||||
if options.python_version:
|
||||
python_versions = [options.python_version]
|
||||
else:
|
||||
python_versions = None
|
||||
|
||||
options.src_dir = os.path.abspath(options.src_dir)
|
||||
install_options = options.install_options or []
|
||||
if options.use_user_site:
|
||||
|
@ -294,7 +289,7 @@ class InstallCommand(RequirementCommand):
|
|||
options=options,
|
||||
session=session,
|
||||
platform=options.platform,
|
||||
python_versions=python_versions,
|
||||
py_version_info=options.python_version,
|
||||
abi=options.abi,
|
||||
implementation=options.implementation,
|
||||
ignore_requires_python=options.ignore_requires_python,
|
||||
|
|
|
@ -29,7 +29,7 @@ from pip._internal.models.candidate import InstallationCandidate
|
|||
from pip._internal.models.format_control import FormatControl
|
||||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.models.link import Link
|
||||
from pip._internal.pep425tags import get_supported
|
||||
from pip._internal.pep425tags import get_supported, version_info_to_nodot
|
||||
from pip._internal.utils.compat import ipaddress
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import (
|
||||
|
@ -604,7 +604,7 @@ class PackageFinder(object):
|
|||
session=None, # type: Optional[PipSession]
|
||||
format_control=None, # type: Optional[FormatControl]
|
||||
platform=None, # type: Optional[str]
|
||||
versions=None, # type: Optional[List[str]]
|
||||
py_version_info=None, # type: Optional[Tuple[int, ...]]
|
||||
abi=None, # type: Optional[str]
|
||||
implementation=None, # type: Optional[str]
|
||||
prefer_binary=False, # type: bool
|
||||
|
@ -624,8 +624,10 @@ class PackageFinder(object):
|
|||
packages that can be built on the platform passed in. These
|
||||
packages will only be downloaded for distribution: they will
|
||||
not be built locally.
|
||||
:param versions: A list of strings or None. This is passed directly
|
||||
to pep425tags.py in the get_supported() method.
|
||||
:param py_version_info: An optional tuple of ints representing the
|
||||
Python version information to use (e.g. `sys.version_info[:3]`).
|
||||
This can have length 1, 2, or 3. This is used to construct the
|
||||
value passed to pep425tags.py's get_supported() function.
|
||||
:param abi: A string or None. This is passed directly
|
||||
to pep425tags.py in the get_supported() method.
|
||||
:param implementation: A string or None. This is passed directly
|
||||
|
@ -659,6 +661,11 @@ class PackageFinder(object):
|
|||
for host in (trusted_hosts if trusted_hosts else [])
|
||||
] # type: List[SecureOrigin]
|
||||
|
||||
if py_version_info:
|
||||
versions = [version_info_to_nodot(py_version_info)]
|
||||
else:
|
||||
versions = None
|
||||
|
||||
# The valid tags to check potential found wheel candidates against
|
||||
valid_tags = get_supported(
|
||||
versions=versions,
|
||||
|
|
|
@ -49,6 +49,12 @@ def get_abbr_impl():
|
|||
return pyimpl
|
||||
|
||||
|
||||
def version_info_to_nodot(version_info):
|
||||
# type: (Tuple[int, ...]) -> str
|
||||
# Only use up to the first two numbers.
|
||||
return ''.join(map(str, version_info[:2]))
|
||||
|
||||
|
||||
def get_impl_ver():
|
||||
# type: () -> str
|
||||
"""Return implementation version."""
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import pytest
|
||||
|
||||
from pip._internal.cli.cmdoptions import _convert_python_version
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, expected', [
|
||||
('2', (2,)),
|
||||
('3', (3,)),
|
||||
('34', (3, 4)),
|
||||
# Test a 2-digit minor version.
|
||||
('310', (3, 10)),
|
||||
])
|
||||
def test_convert_python_version(value, expected):
|
||||
actual = _convert_python_version(value)
|
||||
assert actual == expected
|
|
@ -3,7 +3,7 @@ import os.path
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from mock import Mock, patch
|
||||
from pip._vendor import html5lib, requests
|
||||
|
||||
from pip._internal.download import PipSession
|
||||
|
@ -149,6 +149,34 @@ class TestCandidateEvaluator:
|
|||
assert actual == expected
|
||||
|
||||
|
||||
class TestPackageFinder:
|
||||
|
||||
@pytest.mark.parametrize('version_info, expected', [
|
||||
((2,), ['2']),
|
||||
((3,), ['3']),
|
||||
((3, 6,), ['36']),
|
||||
# Test a tuple of length 3.
|
||||
((3, 6, 5), ['36']),
|
||||
# Test a 2-digit minor version.
|
||||
((3, 10), ['310']),
|
||||
# Test falsey values.
|
||||
(None, None),
|
||||
((), None),
|
||||
])
|
||||
@patch('pip._internal.index.get_supported')
|
||||
def test_create__py_version_info(
|
||||
self, mock_get_supported, version_info, expected,
|
||||
):
|
||||
"""
|
||||
Test that the py_version_info argument is handled correctly.
|
||||
"""
|
||||
PackageFinder.create(
|
||||
[], [], py_version_info=version_info, session=object(),
|
||||
)
|
||||
actual = mock_get_supported.call_args[1]['versions']
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_sort_locations_file_expand_dir(data):
|
||||
"""
|
||||
Test that a file:// dir gets listdir run with expand_dir
|
||||
|
|
|
@ -6,6 +6,21 @@ from mock import patch
|
|||
from pip._internal import pep425tags
|
||||
|
||||
|
||||
@pytest.mark.parametrize('version_info, expected', [
|
||||
((2,), '2'),
|
||||
((2, 8), '28'),
|
||||
((3,), '3'),
|
||||
((3, 6), '36'),
|
||||
# Test a tuple of length 3.
|
||||
((3, 6, 5), '36'),
|
||||
# Test a 2-digit minor version.
|
||||
((3, 10), '310'),
|
||||
])
|
||||
def test_version_info_to_nodot(version_info, expected):
|
||||
actual = pep425tags.version_info_to_nodot(version_info)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
class TestPEP425Tags(object):
|
||||
|
||||
def mock_get_config_var(self, **kwd):
|
||||
|
|
Loading…
Reference in New Issue