Skip to content

Commit 9311049

Browse files
authored
Merge pull request #6684 from cjerdonek/simplify-found-candidates
Simplify FoundCandidates
2 parents a8c66dc + 9d3d369 commit 9311049

File tree

2 files changed

+46
-18
lines changed

2 files changed

+46
-18
lines changed

src/pip/_internal/index.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,17 @@ def make_found_candidates(
500500
prereleases=allow_prereleases,
501501
)
502502
}
503-
return FoundCandidates(candidates, versions=versions, evaluator=self)
503+
504+
# Again, converting version to str to deal with debundling.
505+
applicable_candidates = [
506+
c for c in candidates if str(c.version) in versions
507+
]
508+
509+
return FoundCandidates(
510+
candidates,
511+
applicable_candidates=applicable_candidates,
512+
evaluator=self,
513+
)
504514

505515
def _sort_key(self, candidate):
506516
# type: (InstallationCandidate) -> CandidateSortingKey
@@ -594,21 +604,20 @@ class FoundCandidates(object):
594604

595605
def __init__(
596606
self,
597-
candidates, # type: List[InstallationCandidate]
598-
versions, # type: Set[str]
599-
evaluator, # type: CandidateEvaluator
607+
candidates, # type: List[InstallationCandidate]
608+
applicable_candidates, # type: List[InstallationCandidate]
609+
evaluator, # type: CandidateEvaluator
600610
):
601611
# type: (...) -> None
602612
"""
603613
:param candidates: A sequence of all available candidates found.
604-
:param versions: The applicable versions to filter applicable
605-
candidates.
614+
:param applicable_candidates: The applicable candidates.
606615
:param evaluator: A CandidateEvaluator object to sort applicable
607616
candidates by order of preference.
608617
"""
618+
self._applicable_candidates = applicable_candidates
609619
self._candidates = candidates
610620
self._evaluator = evaluator
611-
self._versions = versions
612621

613622
def iter_all(self):
614623
# type: () -> Iterable[InstallationCandidate]
@@ -618,11 +627,9 @@ def iter_all(self):
618627

619628
def iter_applicable(self):
620629
# type: () -> Iterable[InstallationCandidate]
621-
"""Iterate through candidates matching the versions associated with
622-
this instance.
630+
"""Iterate through the applicable candidates.
623631
"""
624-
# Again, converting version to str to deal with debundling.
625-
return (c for c in self.iter_all() if str(c.version) in self._versions)
632+
return iter(self._applicable_candidates)
626633

627634
def get_best(self):
628635
# type: () -> Optional[InstallationCandidate]

tests/unit/test_index.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55
from mock import Mock
66
from pip._vendor import html5lib, requests
7+
from pip._vendor.packaging.specifiers import SpecifierSet
78

89
from pip._internal.download import PipSession
910
from pip._internal.index import (
@@ -170,6 +171,33 @@ def test_evaluate_link__incompatible_wheel(self):
170171

171172
class TestCandidateEvaluator:
172173

174+
def make_mock_candidate(self, version, yanked_reason=None):
175+
url = 'https://example.com/pkg-{}.tar.gz'.format(version)
176+
link = Link(url, yanked_reason=yanked_reason)
177+
candidate = InstallationCandidate('mypackage', version, link)
178+
179+
return candidate
180+
181+
def test_make_found_candidates(self):
182+
specifier = SpecifierSet('<= 1.11')
183+
versions = ['1.10', '1.11', '1.12']
184+
candidates = [
185+
self.make_mock_candidate(version) for version in versions
186+
]
187+
evaluator = CandidateEvaluator()
188+
found_candidates = evaluator.make_found_candidates(
189+
candidates, specifier=specifier,
190+
)
191+
192+
assert found_candidates._candidates == candidates
193+
assert found_candidates._evaluator is evaluator
194+
expected_applicable = candidates[:2]
195+
assert [str(c.version) for c in expected_applicable] == [
196+
'1.10',
197+
'1.11',
198+
]
199+
assert found_candidates._applicable_candidates == expected_applicable
200+
173201
@pytest.mark.parametrize('yanked_reason, expected', [
174202
# Test a non-yanked file.
175203
(None, 0),
@@ -190,13 +218,6 @@ def test_sort_key__is_yanked(self, yanked_reason, expected):
190218
actual = sort_value[0]
191219
assert actual == expected
192220

193-
def make_mock_candidate(self, version, yanked_reason=None):
194-
url = 'https://example.com/pkg-{}.tar.gz'.format(version)
195-
link = Link(url, yanked_reason=yanked_reason)
196-
candidate = InstallationCandidate('mypackage', version, link)
197-
198-
return candidate
199-
200221
def test_get_best_candidate__no_candidates(self):
201222
"""
202223
Test passing an empty list.

0 commit comments

Comments
 (0)