Merge pull request #11119 from pradyunsg/move-add_requirement-to-legacy-resolver

This commit is contained in:
Pradyun Gedam 2022-05-14 11:10:26 +01:00 committed by GitHub
commit 923cb5a197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 238 additions and 204 deletions

View File

@ -1,13 +1,10 @@
import logging import logging
from collections import OrderedDict from collections import OrderedDict
from typing import Dict, Iterable, List, Optional, Tuple from typing import Dict, List
from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.exceptions import InstallationError
from pip._internal.models.wheel import Wheel
from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils import compatibility_tags
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -51,123 +48,6 @@ class RequirementSet:
project_name = canonicalize_name(install_req.name) project_name = canonicalize_name(install_req.name)
self.requirements[project_name] = install_req self.requirements[project_name] = install_req
def add_requirement(
self,
install_req: InstallRequirement,
parent_req_name: Optional[str] = None,
extras_requested: Optional[Iterable[str]] = None,
) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]]:
"""Add install_req as a requirement to install.
:param parent_req_name: The name of the requirement that needed this
added. The name is used because when multiple unnamed requirements
resolve to the same name, we could otherwise end up with dependency
links that point outside the Requirements set. parent_req must
already be added. Note that None implies that this is a user
supplied requirement, vs an inferred one.
:param extras_requested: an iterable of extras used to evaluate the
environment markers.
:return: Additional requirements to scan. That is either [] if
the requirement is not applicable, or [install_req] if the
requirement is applicable and has just been added.
"""
# If the markers do not match, ignore this requirement.
if not install_req.match_markers(extras_requested):
logger.info(
"Ignoring %s: markers '%s' don't match your environment",
install_req.name,
install_req.markers,
)
return [], None
# If the wheel is not supported, raise an error.
# Should check this after filtering out based on environment markers to
# allow specifying different wheels based on the environment/OS, in a
# single requirements file.
if install_req.link and install_req.link.is_wheel:
wheel = Wheel(install_req.link.filename)
tags = compatibility_tags.get_supported()
if self.check_supported_wheels and not wheel.supported(tags):
raise InstallationError(
"{} is not a supported wheel on this platform.".format(
wheel.filename
)
)
# This next bit is really a sanity check.
assert (
not install_req.user_supplied or parent_req_name is None
), "a user supplied req shouldn't have a parent"
# Unnamed requirements are scanned again and the requirement won't be
# added as a dependency until after scanning.
if not install_req.name:
self.add_unnamed_requirement(install_req)
return [install_req], None
try:
existing_req: Optional[InstallRequirement] = self.get_requirement(
install_req.name
)
except KeyError:
existing_req = None
has_conflicting_requirement = (
parent_req_name is None
and existing_req
and not existing_req.constraint
and existing_req.extras == install_req.extras
and existing_req.req
and install_req.req
and existing_req.req.specifier != install_req.req.specifier
)
if has_conflicting_requirement:
raise InstallationError(
"Double requirement given: {} (already in {}, name={!r})".format(
install_req, existing_req, install_req.name
)
)
# When no existing requirement exists, add the requirement as a
# dependency and it will be scanned again after.
if not existing_req:
self.add_named_requirement(install_req)
# We'd want to rescan this requirement later
return [install_req], install_req
# Assume there's no need to scan, and that we've already
# encountered this for scanning.
if install_req.constraint or not existing_req.constraint:
return [], existing_req
does_not_satisfy_constraint = install_req.link and not (
existing_req.link and install_req.link.path == existing_req.link.path
)
if does_not_satisfy_constraint:
raise InstallationError(
"Could not satisfy constraints for '{}': "
"installation from path or url cannot be "
"constrained to a version".format(install_req.name)
)
# If we're now installing a constraint, mark the existing
# object for real installation.
existing_req.constraint = False
# If we're now installing a user supplied requirement,
# mark the existing object as such.
if install_req.user_supplied:
existing_req.user_supplied = True
existing_req.extras = tuple(
sorted(set(existing_req.extras) | set(install_req.extras))
)
logger.debug(
"Setting %s extras to: %s",
existing_req,
existing_req.extras,
)
# Return the existing requirement for addition to the parent and
# scanning again.
return [existing_req], existing_req
def has_requirement(self, name: str) -> bool: def has_requirement(self, name: str) -> bool:
project_name = canonicalize_name(name) project_name = canonicalize_name(name)

View File

@ -28,12 +28,14 @@ from pip._internal.exceptions import (
DistributionNotFound, DistributionNotFound,
HashError, HashError,
HashErrors, HashErrors,
InstallationError,
NoneMetadataError, NoneMetadataError,
UnsupportedPythonVersion, UnsupportedPythonVersion,
) )
from pip._internal.index.package_finder import PackageFinder from pip._internal.index.package_finder import PackageFinder
from pip._internal.metadata import BaseDistribution from pip._internal.metadata import BaseDistribution
from pip._internal.models.link import Link from pip._internal.models.link import Link
from pip._internal.models.wheel import Wheel
from pip._internal.operations.prepare import RequirementPreparer from pip._internal.operations.prepare import RequirementPreparer
from pip._internal.req.req_install import ( from pip._internal.req.req_install import (
InstallRequirement, InstallRequirement,
@ -41,6 +43,7 @@ from pip._internal.req.req_install import (
) )
from pip._internal.req.req_set import RequirementSet from pip._internal.req.req_set import RequirementSet
from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider
from pip._internal.utils import compatibility_tags
from pip._internal.utils.compatibility_tags import get_supported from pip._internal.utils.compatibility_tags import get_supported
from pip._internal.utils.logging import indent_log from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import normalize_version_info from pip._internal.utils.misc import normalize_version_info
@ -168,7 +171,7 @@ class Resolver(BaseResolver):
for req in root_reqs: for req in root_reqs:
if req.constraint: if req.constraint:
check_invalid_constraint_type(req) check_invalid_constraint_type(req)
requirement_set.add_requirement(req) self._add_requirement_to_set(requirement_set, req)
# Actually prepare the files, and collect any exceptions. Most hash # Actually prepare the files, and collect any exceptions. Most hash
# exceptions cannot be checked ahead of time, because # exceptions cannot be checked ahead of time, because
@ -188,6 +191,124 @@ class Resolver(BaseResolver):
return requirement_set return requirement_set
def _add_requirement_to_set(
self,
requirement_set: RequirementSet,
install_req: InstallRequirement,
parent_req_name: Optional[str] = None,
extras_requested: Optional[Iterable[str]] = None,
) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]]:
"""Add install_req as a requirement to install.
:param parent_req_name: The name of the requirement that needed this
added. The name is used because when multiple unnamed requirements
resolve to the same name, we could otherwise end up with dependency
links that point outside the Requirements set. parent_req must
already be added. Note that None implies that this is a user
supplied requirement, vs an inferred one.
:param extras_requested: an iterable of extras used to evaluate the
environment markers.
:return: Additional requirements to scan. That is either [] if
the requirement is not applicable, or [install_req] if the
requirement is applicable and has just been added.
"""
# If the markers do not match, ignore this requirement.
if not install_req.match_markers(extras_requested):
logger.info(
"Ignoring %s: markers '%s' don't match your environment",
install_req.name,
install_req.markers,
)
return [], None
# If the wheel is not supported, raise an error.
# Should check this after filtering out based on environment markers to
# allow specifying different wheels based on the environment/OS, in a
# single requirements file.
if install_req.link and install_req.link.is_wheel:
wheel = Wheel(install_req.link.filename)
tags = compatibility_tags.get_supported()
if requirement_set.check_supported_wheels and not wheel.supported(tags):
raise InstallationError(
"{} is not a supported wheel on this platform.".format(
wheel.filename
)
)
# This next bit is really a sanity check.
assert (
not install_req.user_supplied or parent_req_name is None
), "a user supplied req shouldn't have a parent"
# Unnamed requirements are scanned again and the requirement won't be
# added as a dependency until after scanning.
if not install_req.name:
requirement_set.add_unnamed_requirement(install_req)
return [install_req], None
try:
existing_req: Optional[
InstallRequirement
] = requirement_set.get_requirement(install_req.name)
except KeyError:
existing_req = None
has_conflicting_requirement = (
parent_req_name is None
and existing_req
and not existing_req.constraint
and existing_req.extras == install_req.extras
and existing_req.req
and install_req.req
and existing_req.req.specifier != install_req.req.specifier
)
if has_conflicting_requirement:
raise InstallationError(
"Double requirement given: {} (already in {}, name={!r})".format(
install_req, existing_req, install_req.name
)
)
# When no existing requirement exists, add the requirement as a
# dependency and it will be scanned again after.
if not existing_req:
requirement_set.add_named_requirement(install_req)
# We'd want to rescan this requirement later
return [install_req], install_req
# Assume there's no need to scan, and that we've already
# encountered this for scanning.
if install_req.constraint or not existing_req.constraint:
return [], existing_req
does_not_satisfy_constraint = install_req.link and not (
existing_req.link and install_req.link.path == existing_req.link.path
)
if does_not_satisfy_constraint:
raise InstallationError(
"Could not satisfy constraints for '{}': "
"installation from path or url cannot be "
"constrained to a version".format(install_req.name)
)
# If we're now installing a constraint, mark the existing
# object for real installation.
existing_req.constraint = False
# If we're now installing a user supplied requirement,
# mark the existing object as such.
if install_req.user_supplied:
existing_req.user_supplied = True
existing_req.extras = tuple(
sorted(set(existing_req.extras) | set(install_req.extras))
)
logger.debug(
"Setting %s extras to: %s",
existing_req,
existing_req.extras,
)
# Return the existing requirement for addition to the parent and
# scanning again.
return [existing_req], existing_req
def _is_upgrade_allowed(self, req: InstallRequirement) -> bool: def _is_upgrade_allowed(self, req: InstallRequirement) -> bool:
if self.upgrade_strategy == "to-satisfy-only": if self.upgrade_strategy == "to-satisfy-only":
return False return False
@ -393,7 +514,8 @@ class Resolver(BaseResolver):
# the legacy resolver so I'm just not going to bother refactoring. # the legacy resolver so I'm just not going to bother refactoring.
sub_install_req = self._make_install_req(str(subreq), req_to_install) sub_install_req = self._make_install_req(str(subreq), req_to_install)
parent_req_name = req_to_install.name parent_req_name = req_to_install.name
to_scan_again, add_to_parent = requirement_set.add_requirement( to_scan_again, add_to_parent = self._add_requirement_to_set(
requirement_set,
sub_install_req, sub_install_req,
parent_req_name=parent_req_name, parent_req_name=parent_req_name,
extras_requested=extras_requested, extras_requested=extras_requested,
@ -410,7 +532,9 @@ class Resolver(BaseResolver):
# 'unnamed' requirements can only come from being directly # 'unnamed' requirements can only come from being directly
# provided by the user. # provided by the user.
assert req_to_install.user_supplied assert req_to_install.user_supplied
requirement_set.add_requirement(req_to_install, parent_req_name=None) self._add_requirement_to_set(
requirement_set, req_to_install, parent_req_name=None
)
if not self.ignore_dependencies: if not self.ignore_dependencies:
if req_to_install.extras: if req_to_install.extras:

View File

@ -123,7 +123,7 @@ class TestRequirementSet:
reqset = RequirementSet() reqset = RequirementSet()
req = install_req_from_line("simple") req = install_req_from_line("simple")
req.user_supplied = True req.user_supplied = True
reqset.add_requirement(req) reqset.add_named_requirement(req)
finder = make_test_finder(find_links=[data.find_links]) finder = make_test_finder(find_links=[data.find_links])
with self._basic_resolver(finder) as resolver: with self._basic_resolver(finder) as resolver:
with pytest.raises( with pytest.raises(
@ -144,7 +144,7 @@ class TestRequirementSet:
reqset = RequirementSet() reqset = RequirementSet()
req = install_req_from_editable(data.packages.joinpath("LocalEnvironMarker")) req = install_req_from_editable(data.packages.joinpath("LocalEnvironMarker"))
req.user_supplied = True req.user_supplied = True
reqset.add_requirement(req) reqset.add_unnamed_requirement(req)
finder = make_test_finder(find_links=[data.find_links]) finder = make_test_finder(find_links=[data.find_links])
with self._basic_resolver(finder) as resolver: with self._basic_resolver(finder) as resolver:
reqset = resolver.resolve(reqset.all_requirements, True) reqset = resolver.resolve(reqset.all_requirements, True)
@ -155,7 +155,9 @@ class TestRequirementSet:
are missing. are missing.
""" """
reqset = RequirementSet() reqset = RequirementSet()
reqset.add_requirement(get_processed_req_from_line("simple==1.0", lineno=1)) reqset.add_named_requirement(
get_processed_req_from_line("simple==1.0", lineno=1)
)
finder = make_test_finder(find_links=[data.find_links]) finder = make_test_finder(find_links=[data.find_links])
@ -194,14 +196,14 @@ class TestRequirementSet:
""" """
reqset = RequirementSet() reqset = RequirementSet()
reqset.add_requirement( reqset.add_unnamed_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"git+git://github.com/pypa/pip-test-package --hash=sha256:123", "git+git://github.com/pypa/pip-test-package --hash=sha256:123",
lineno=1, lineno=1,
) )
) )
dir_path = data.packages.joinpath("FSPkg") dir_path = data.packages.joinpath("FSPkg")
reqset.add_requirement( reqset.add_unnamed_requirement(
get_processed_req_from_line( get_processed_req_from_line(
f"file://{dir_path}", f"file://{dir_path}",
lineno=2, lineno=2,
@ -235,7 +237,7 @@ class TestRequirementSet:
""" """
reqset = RequirementSet() reqset = RequirementSet()
# Test that there must be exactly 1 specifier: # Test that there must be exactly 1 specifier:
reqset.add_requirement( reqset.add_named_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985" "simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985"
"250c1c83fd68df5911dd", "250c1c83fd68df5911dd",
@ -243,7 +245,7 @@ class TestRequirementSet:
) )
) )
# Test that the operator must be ==: # Test that the operator must be ==:
reqset.add_requirement( reqset.add_named_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0" "simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0"
"123f6a7e44a9115db1ef945d4d92c123dfe21815a06", "123f6a7e44a9115db1ef945d4d92c123dfe21815a06",
@ -267,7 +269,7 @@ class TestRequirementSet:
"""A hash mismatch should raise an error.""" """A hash mismatch should raise an error."""
file_url = path_to_url((data.packages / "simple-1.0.tar.gz").resolve()) file_url = path_to_url((data.packages / "simple-1.0.tar.gz").resolve())
reqset = RequirementSet() reqset = RequirementSet()
reqset.add_requirement( reqset.add_unnamed_requirement(
get_processed_req_from_line( get_processed_req_from_line(
f"{file_url} --hash=sha256:badbad", f"{file_url} --hash=sha256:badbad",
lineno=1, lineno=1,
@ -292,7 +294,7 @@ class TestRequirementSet:
dependencies get complained about when --require-hashes is on.""" dependencies get complained about when --require-hashes is on."""
reqset = RequirementSet() reqset = RequirementSet()
finder = make_test_finder(find_links=[data.find_links]) finder = make_test_finder(find_links=[data.find_links])
reqset.add_requirement( reqset.add_named_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"TopoRequires2==0.0.1 " # requires TopoRequires "TopoRequires2==0.0.1 " # requires TopoRequires
"--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd" "--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd"
@ -322,7 +324,7 @@ class TestRequirementSet:
""" """
reqset = RequirementSet() reqset = RequirementSet()
reqset.add_requirement( reqset.add_named_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"TopoRequires2==0.0.1 " # requires TopoRequires "TopoRequires2==0.0.1 " # requires TopoRequires
"--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd" "--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd"
@ -330,7 +332,7 @@ class TestRequirementSet:
lineno=1, lineno=1,
) )
) )
reqset.add_requirement( reqset.add_named_requirement(
get_processed_req_from_line( get_processed_req_from_line(
"TopoRequires==0.0.1 " "TopoRequires==0.0.1 "
"--hash=sha256:d6dd1e22e60df512fdcf3640ced3039b3b02a56ab2cee81ebcb" "--hash=sha256:d6dd1e22e60df512fdcf3640ced3039b3b02a56ab2cee81ebcb"
@ -382,32 +384,6 @@ class TestInstallRequirement:
assert req.link.scheme == "https" assert req.link.scheme == "https"
assert req.link.url == url assert req.link.url == url
def test_unsupported_wheel_link_requirement_raises(self) -> None:
reqset = RequirementSet()
req = install_req_from_line(
"https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl",
)
assert req.link is not None
assert req.link.is_wheel
assert req.link.scheme == "https"
with pytest.raises(InstallationError):
reqset.add_requirement(req)
def test_unsupported_wheel_local_file_requirement_raises(
self, data: TestData
) -> None:
reqset = RequirementSet()
req = install_req_from_line(
data.packages.joinpath("simple.dist-0.1-py1-none-invalid.whl"),
)
assert req.link is not None
assert req.link.is_wheel
assert req.link.scheme == "file"
with pytest.raises(InstallationError):
reqset.add_requirement(req)
def test_str(self) -> None: def test_str(self) -> None:
req = install_req_from_line("simple==0.1") req = install_req_from_line("simple==0.1")
assert str(req) == "simple==0.1" assert str(req) == "simple==0.1"
@ -658,19 +634,6 @@ def test_parse_editable_local_extras(
) )
def test_exclusive_environment_markers() -> None:
"""Make sure RequirementSet accepts several excluding env markers"""
eq36 = install_req_from_line("Django>=1.6.10,<1.7 ; python_version == '3.6'")
eq36.user_supplied = True
ne36 = install_req_from_line("Django>=1.6.10,<1.8 ; python_version != '3.6'")
ne36.user_supplied = True
req_set = RequirementSet()
req_set.add_requirement(eq36)
req_set.add_requirement(ne36)
assert req_set.has_requirement("Django")
def test_mismatched_versions(caplog: pytest.LogCaptureFixture) -> None: def test_mismatched_versions(caplog: pytest.LogCaptureFixture) -> None:
req = InstallRequirement( req = InstallRequirement(
req=Requirement("simplewheel==2.0"), req=Requirement("simplewheel==2.0"),

View File

@ -7,15 +7,20 @@ import pytest
from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.specifiers import SpecifierSet
from pip._vendor.packaging.utils import NormalizedName from pip._vendor.packaging.utils import NormalizedName
from pip._internal.exceptions import NoneMetadataError, UnsupportedPythonVersion from pip._internal.exceptions import (
InstallationError,
NoneMetadataError,
UnsupportedPythonVersion,
)
from pip._internal.metadata import BaseDistribution from pip._internal.metadata import BaseDistribution
from pip._internal.models.candidate import InstallationCandidate from pip._internal.models.candidate import InstallationCandidate
from pip._internal.req.constructors import install_req_from_line from pip._internal.req.constructors import install_req_from_line
from pip._internal.req.req_set import RequirementSet
from pip._internal.resolution.legacy.resolver import ( from pip._internal.resolution.legacy.resolver import (
Resolver, Resolver,
_check_dist_requires_python, _check_dist_requires_python,
) )
from tests.lib import make_test_finder from tests.lib import TestData, make_test_finder
from tests.lib.index import make_mock_candidate from tests.lib.index import make_mock_candidate
T = TypeVar("T") T = TypeVar("T")
@ -50,8 +55,94 @@ def make_fake_dist(
return klass(metadata) # type: ignore[call-arg] return klass(metadata) # type: ignore[call-arg]
class TestCheckDistRequiresPython: def make_test_resolver(
monkeypatch: pytest.MonkeyPatch,
mock_candidates: List[InstallationCandidate],
) -> Resolver:
def _find_candidates(project_name: str) -> List[InstallationCandidate]:
return mock_candidates
finder = make_test_finder()
monkeypatch.setattr(finder, "find_all_candidates", _find_candidates)
return Resolver(
finder=finder,
preparer=mock.Mock(), # Not used.
make_install_req=install_req_from_line,
wheel_cache=None,
use_user_site=False,
force_reinstall=False,
ignore_dependencies=False,
ignore_installed=False,
ignore_requires_python=False,
upgrade_strategy="to-satisfy-only",
)
class TestAddRequirement:
"""
Test _add_requirement_to_set().
"""
def test_unsupported_wheel_link_requirement_raises(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
# GIVEN
resolver = make_test_resolver(monkeypatch, [])
requirement_set = RequirementSet(check_supported_wheels=True)
install_req = install_req_from_line(
"https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl",
)
assert install_req.link is not None
assert install_req.link.is_wheel
assert install_req.link.scheme == "https"
# WHEN / THEN
with pytest.raises(InstallationError):
resolver._add_requirement_to_set(requirement_set, install_req)
def test_unsupported_wheel_local_file_requirement_raises(
self, data: TestData, monkeypatch: pytest.MonkeyPatch
) -> None:
# GIVEN
resolver = make_test_resolver(monkeypatch, [])
requirement_set = RequirementSet(check_supported_wheels=True)
install_req = install_req_from_line(
data.packages.joinpath("simple.dist-0.1-py1-none-invalid.whl"),
)
assert install_req.link is not None
assert install_req.link.is_wheel
assert install_req.link.scheme == "file"
# WHEN / THEN
with pytest.raises(InstallationError):
resolver._add_requirement_to_set(requirement_set, install_req)
def test_exclusive_environment_markers(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Make sure excluding environment markers are handled correctly."""
# GIVEN
resolver = make_test_resolver(monkeypatch, [])
requirement_set = RequirementSet(check_supported_wheels=True)
eq36 = install_req_from_line("Django>=1.6.10,<1.7 ; python_version == '3.6'")
eq36.user_supplied = True
ne36 = install_req_from_line("Django>=1.6.10,<1.8 ; python_version != '3.6'")
ne36.user_supplied = True
# WHEN
resolver._add_requirement_to_set(requirement_set, eq36)
resolver._add_requirement_to_set(requirement_set, ne36)
# THEN
assert requirement_set.has_requirement("Django")
assert len(requirement_set.all_requirements) == 1
class TestCheckDistRequiresPython:
""" """
Test _check_dist_requires_python(). Test _check_dist_requires_python().
""" """
@ -179,30 +270,6 @@ class TestYankedWarning:
Test _populate_link() emits warning if one or more candidates are yanked. Test _populate_link() emits warning if one or more candidates are yanked.
""" """
def _make_test_resolver(
self,
monkeypatch: pytest.MonkeyPatch,
mock_candidates: List[InstallationCandidate],
) -> Resolver:
def _find_candidates(project_name: str) -> List[InstallationCandidate]:
return mock_candidates
finder = make_test_finder()
monkeypatch.setattr(finder, "find_all_candidates", _find_candidates)
return Resolver(
finder=finder,
preparer=mock.Mock(), # Not used.
make_install_req=install_req_from_line,
wheel_cache=None,
use_user_site=False,
force_reinstall=False,
ignore_dependencies=False,
ignore_installed=False,
ignore_requires_python=False,
upgrade_strategy="to-satisfy-only",
)
def test_sort_best_candidate__has_non_yanked( def test_sort_best_candidate__has_non_yanked(
self, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch self, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch
) -> None: ) -> None:
@ -219,7 +286,7 @@ class TestYankedWarning:
] ]
ireq = install_req_from_line("pkg") ireq = install_req_from_line("pkg")
resolver = self._make_test_resolver(monkeypatch, candidates) resolver = make_test_resolver(monkeypatch, candidates)
resolver._populate_link(ireq) resolver._populate_link(ireq)
assert ireq.link == candidates[0].link assert ireq.link == candidates[0].link
@ -243,7 +310,7 @@ class TestYankedWarning:
] ]
ireq = install_req_from_line("pkg") ireq = install_req_from_line("pkg")
resolver = self._make_test_resolver(monkeypatch, candidates) resolver = make_test_resolver(monkeypatch, candidates)
resolver._populate_link(ireq) resolver._populate_link(ireq)
assert ireq.link == candidates[1].link assert ireq.link == candidates[1].link
@ -287,7 +354,7 @@ class TestYankedWarning:
] ]
ireq = install_req_from_line("pkg") ireq = install_req_from_line("pkg")
resolver = self._make_test_resolver(monkeypatch, candidates) resolver = make_test_resolver(monkeypatch, candidates)
resolver._populate_link(ireq) resolver._populate_link(ireq)
assert ireq.link == candidates[0].link assert ireq.link == candidates[0].link