Move check_dist_requires_python() to resolve.py.

This commit is contained in:
Chris Jerdonek 2019-05-23 00:03:56 -07:00
parent eeb74aeb29
commit cc70cf5ba3
4 changed files with 68 additions and 55 deletions

View File

@ -15,6 +15,9 @@ import sys
from collections import defaultdict
from itertools import chain
from pip._vendor.packaging import specifiers
from pip._internal import exceptions
from pip._internal.exceptions import (
BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors,
UnsupportedPythonVersion,
@ -22,11 +25,12 @@ from pip._internal.exceptions import (
from pip._internal.req.constructors import install_req_from_req_string
from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import dist_in_usersite, ensure_dir
from pip._internal.utils.packaging import check_dist_requires_python
from pip._internal.utils.packaging import check_requires_python, get_metadata
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
if MYPY_CHECK_RUNNING:
from typing import Optional, DefaultDict, List, Set
from typing import DefaultDict, List, Optional, Set, Tuple
from pip._vendor import pkg_resources
from pip._internal.download import PipSession
from pip._internal.req.req_install import InstallRequirement
from pip._internal.index import PackageFinder
@ -39,6 +43,35 @@ if MYPY_CHECK_RUNNING:
logger = logging.getLogger(__name__)
def check_dist_requires_python(
dist, # type: pkg_resources.Distribution
version_info, # type: Optional[Tuple[int, ...]]
):
# type: (...) -> None
"""
:param version_info: A 3-tuple of ints representing the Python
major-minor-micro version to check (e.g. `sys.version_info[:3]`).
"""
pkg_info_dict = get_metadata(dist)
requires_python = pkg_info_dict.get('Requires-Python')
try:
if not check_requires_python(
requires_python, version_info=version_info,
):
raise exceptions.UnsupportedPythonVersion(
"%s requires Python '%s' but the running Python is %s" % (
dist.project_name,
requires_python,
'.'.join(map(str, version_info)),)
)
except specifiers.InvalidSpecifier as e:
logger.warning(
"Package %s has an invalid Requires-Python entry %s - %s",
dist.project_name, requires_python, e,
)
return
class Resolver(object):
"""Resolves which packages need to be installed/uninstalled to perform \
the requested operation without breaking the requirements of any package.

View File

@ -6,7 +6,6 @@ from email.parser import FeedParser
from pip._vendor import pkg_resources
from pip._vendor.packaging import specifiers, version
from pip._internal import exceptions
from pip._internal.utils.misc import display_path
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
@ -58,31 +57,6 @@ def get_metadata(dist):
return feed_parser.close()
def check_dist_requires_python(dist, version_info):
"""
:param version_info: A 3-tuple of ints representing the Python
major-minor-micro version to check (e.g. `sys.version_info[:3]`).
"""
pkg_info_dict = get_metadata(dist)
requires_python = pkg_info_dict.get('Requires-Python')
try:
if not check_requires_python(
requires_python, version_info=version_info,
):
raise exceptions.UnsupportedPythonVersion(
"%s requires Python '%s' but the running Python is %s" % (
dist.project_name,
requires_python,
'.'.join(map(str, version_info)),)
)
except specifiers.InvalidSpecifier as e:
logger.warning(
"Package %s has an invalid Requires-Python entry %s - %s",
dist.project_name, requires_python, e,
)
return
def get_installer(dist):
# type: (Distribution) -> str
if dist.has_metadata('INSTALLER'):

View File

@ -0,0 +1,32 @@
import sys
import pytest
from mock import Mock
from pip._internal.exceptions import UnsupportedPythonVersion
from pip._internal.resolve import check_dist_requires_python
class TestCheckRequiresPython(object):
@pytest.mark.parametrize(
("metadata", "should_raise"),
[
("Name: test\n", False),
("Name: test\nRequires-Python:", False),
("Name: test\nRequires-Python: invalid_spec", False),
("Name: test\nRequires-Python: <=1", True),
],
)
def test_check_requires(self, metadata, should_raise):
fake_dist = Mock(
has_metadata=lambda _: True,
get_metadata=lambda _: metadata)
version_info = sys.version_info[:3]
if should_raise:
with pytest.raises(UnsupportedPythonVersion):
check_dist_requires_python(
fake_dist, version_info=version_info,
)
else:
check_dist_requires_python(fake_dist, version_info=version_info)

View File

@ -20,7 +20,7 @@ import pytest
from mock import Mock, patch
from pip._internal.exceptions import (
HashMismatch, HashMissing, InstallationError, UnsupportedPythonVersion,
HashMismatch, HashMissing, InstallationError,
)
from pip._internal.utils.encoding import BOMS, auto_decode
from pip._internal.utils.glibc import check_glibc_version
@ -31,7 +31,6 @@ from pip._internal.utils.misc import (
redact_password_from_url, remove_auth_from_url, rmtree,
split_auth_from_netloc, split_auth_netloc_from_url, untar_file, unzip_file,
)
from pip._internal.utils.packaging import check_dist_requires_python
from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory
from pip._internal.utils.ui import SpinnerInterface
@ -699,31 +698,6 @@ class TestGlibc(object):
assert False
class TestCheckRequiresPython(object):
@pytest.mark.parametrize(
("metadata", "should_raise"),
[
("Name: test\n", False),
("Name: test\nRequires-Python:", False),
("Name: test\nRequires-Python: invalid_spec", False),
("Name: test\nRequires-Python: <=1", True),
],
)
def test_check_requires(self, metadata, should_raise):
fake_dist = Mock(
has_metadata=lambda _: True,
get_metadata=lambda _: metadata)
version_info = sys.version_info[:3]
if should_raise:
with pytest.raises(UnsupportedPythonVersion):
check_dist_requires_python(
fake_dist, version_info=version_info,
)
else:
check_dist_requires_python(fake_dist, version_info=version_info)
class TestGetProg(object):
@pytest.mark.parametrize(