Skip to content

Commit ee5716c

Browse files
authored
Merge pull request #6719 from cjerdonek/candidate-evaluator-specifier
Pass the specifier to CandidateEvaluator via create() instead of get_applicable_candidates()
2 parents 90fa087 + 2de3804 commit ee5716c

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

src/pip/_internal/index.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ def create(
550550
target_python=None, # type: Optional[TargetPython]
551551
prefer_binary=False, # type: bool
552552
allow_all_prereleases=False, # type: bool
553-
hashes=None, # type: Optional[Hashes]
553+
specifier=None, # type: Optional[specifiers.BaseSpecifier]
554+
hashes=None, # type: Optional[Hashes]
554555
):
555556
# type: (...) -> CandidateEvaluator
556557
"""Create a CandidateEvaluator object.
@@ -562,12 +563,15 @@ def create(
562563
"""
563564
if target_python is None:
564565
target_python = TargetPython()
566+
if specifier is None:
567+
specifier = specifiers.SpecifierSet()
565568

566569
supported_tags = target_python.get_tags()
567570

568571
return cls(
569572
project_name=project_name,
570573
supported_tags=supported_tags,
574+
specifier=specifier,
571575
prefer_binary=prefer_binary,
572576
allow_all_prereleases=allow_all_prereleases,
573577
hashes=hashes,
@@ -577,6 +581,7 @@ def __init__(
577581
self,
578582
project_name, # type: str
579583
supported_tags, # type: List[Pep425Tag]
584+
specifier, # type: specifiers.BaseSpecifier
580585
prefer_binary=False, # type: bool
581586
allow_all_prereleases=False, # type: bool
582587
hashes=None, # type: Optional[Hashes]
@@ -590,19 +595,20 @@ def __init__(
590595
self._hashes = hashes
591596
self._prefer_binary = prefer_binary
592597
self._project_name = project_name
598+
self._specifier = specifier
593599
self._supported_tags = supported_tags
594600

595601
def get_applicable_candidates(
596602
self,
597603
candidates, # type: List[InstallationCandidate]
598-
specifier, # type: specifiers.BaseSpecifier
599604
):
600605
# type: (...) -> List[InstallationCandidate]
601606
"""
602607
Return the applicable candidates from a list of candidates.
603608
"""
604609
# Using None infers from the specifier instead.
605610
allow_prereleases = self._allow_all_prereleases or None
611+
specifier = self._specifier
606612
versions = {
607613
str(v) for v in specifier.filter(
608614
# We turn the version object into a str here because otherwise
@@ -631,7 +637,6 @@ def get_applicable_candidates(
631637
def make_found_candidates(
632638
self,
633639
candidates, # type: List[InstallationCandidate]
634-
specifier=None, # type: Optional[specifiers.BaseSpecifier]
635640
):
636641
# type: (...) -> FoundCandidates
637642
"""
@@ -641,13 +646,7 @@ def make_found_candidates(
641646
(e.g. `packaging.specifiers.SpecifierSet`) to filter applicable
642647
versions.
643648
"""
644-
if specifier is None:
645-
specifier = specifiers.SpecifierSet()
646-
647-
applicable_candidates = self.get_applicable_candidates(
648-
candidates=candidates,
649-
specifier=specifier,
650-
)
649+
applicable_candidates = self.get_applicable_candidates(candidates)
651650

652651
return FoundCandidates(
653652
candidates,
@@ -1149,8 +1148,9 @@ def find_all_candidates(self, project_name):
11491148

11501149
def make_candidate_evaluator(
11511150
self,
1152-
project_name, # type: str
1153-
hashes=None, # type: Optional[Hashes]
1151+
project_name, # type: str
1152+
specifier=None, # type: Optional[specifiers.BaseSpecifier]
1153+
hashes=None, # type: Optional[Hashes]
11541154
):
11551155
# type: (...) -> CandidateEvaluator
11561156
"""Create a CandidateEvaluator object to use.
@@ -1161,6 +1161,7 @@ def make_candidate_evaluator(
11611161
target_python=self._target_python,
11621162
prefer_binary=candidate_prefs.prefer_binary,
11631163
allow_all_prereleases=candidate_prefs.allow_all_prereleases,
1164+
specifier=specifier,
11641165
hashes=hashes,
11651166
)
11661167

@@ -1182,11 +1183,10 @@ def find_candidates(
11821183
candidates = self.find_all_candidates(project_name)
11831184
candidate_evaluator = self.make_candidate_evaluator(
11841185
project_name=project_name,
1186+
specifier=specifier,
11851187
hashes=hashes,
11861188
)
1187-
return candidate_evaluator.make_found_candidates(
1188-
candidates, specifier=specifier,
1189-
)
1189+
return candidate_evaluator.make_found_candidates(candidates)
11901190

11911191
def find_requirement(self, req, upgrade):
11921192
# type: (InstallRequirement, bool) -> Optional[Link]

tests/unit/test_finder.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import pytest
55
from mock import Mock, patch
6+
from pip._vendor.packaging.specifiers import SpecifierSet
67
from pkg_resources import parse_version
78

89
import pip._internal.pep425tags
@@ -216,7 +217,10 @@ def test_link_sorting(self):
216217
('pyT', 'TEST', 'any'),
217218
('pyT', 'none', 'any'),
218219
]
219-
evaluator = CandidateEvaluator('my-project', supported_tags=valid_tags)
220+
specifier = SpecifierSet()
221+
evaluator = CandidateEvaluator(
222+
'my-project', supported_tags=valid_tags, specifier=specifier,
223+
)
220224
sort_key = evaluator._sort_key
221225
results = sorted(links, key=sort_key, reverse=True)
222226
results2 = sorted(reversed(links), key=sort_key, reverse=True)

tests/unit/test_index.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,17 @@ class TestCandidateEvaluator:
299299
def test_create(self, allow_all_prereleases, prefer_binary):
300300
target_python = TargetPython()
301301
target_python._valid_tags = [('py36', 'none', 'any')]
302+
specifier = SpecifierSet()
302303
evaluator = CandidateEvaluator.create(
303304
project_name='my-project',
304305
target_python=target_python,
305306
allow_all_prereleases=allow_all_prereleases,
306307
prefer_binary=prefer_binary,
308+
specifier=specifier,
307309
)
308310
assert evaluator._allow_all_prereleases == allow_all_prereleases
309311
assert evaluator._prefer_binary == prefer_binary
312+
assert evaluator._specifier is specifier
310313
assert evaluator._supported_tags == [('py36', 'none', 'any')]
311314

312315
def test_create__target_python_none(self):
@@ -317,16 +320,25 @@ def test_create__target_python_none(self):
317320
expected_tags = get_supported()
318321
assert evaluator._supported_tags == expected_tags
319322

323+
def test_create__specifier_none(self):
324+
"""
325+
Test passing specifier=None.
326+
"""
327+
evaluator = CandidateEvaluator.create('my-project')
328+
expected_specifier = SpecifierSet()
329+
assert evaluator._specifier == expected_specifier
330+
320331
def test_get_applicable_candidates(self):
321332
specifier = SpecifierSet('<= 1.11')
322333
versions = ['1.10', '1.11', '1.12']
323334
candidates = [
324335
make_mock_candidate(version) for version in versions
325336
]
326-
evaluator = CandidateEvaluator.create('my-project')
327-
actual = evaluator.get_applicable_candidates(
328-
candidates, specifier=specifier,
337+
evaluator = CandidateEvaluator.create(
338+
'my-project',
339+
specifier=specifier,
329340
)
341+
actual = evaluator.get_applicable_candidates(candidates)
330342
expected_applicable = candidates[:2]
331343
assert [str(c.version) for c in expected_applicable] == [
332344
'1.10',
@@ -347,7 +359,6 @@ def test_get_applicable_candidates__hashes(
347359
"""
348360
Test a non-None hashes value.
349361
"""
350-
# specifier = SpecifierSet('<= 1.1')
351362
candidates = [
352363
make_mock_candidate('1.0'),
353364
make_mock_candidate('1.1', hex_digest=(64 * 'a')),
@@ -357,10 +368,12 @@ def test_get_applicable_candidates__hashes(
357368
'sha256': [64 * 'b'],
358369
}
359370
hashes = Hashes(hashes_data)
360-
evaluator = CandidateEvaluator.create('my-project', hashes=hashes)
361-
actual = evaluator.get_applicable_candidates(
362-
candidates, specifier=specifier,
371+
evaluator = CandidateEvaluator.create(
372+
'my-project',
373+
specifier=specifier,
374+
hashes=hashes,
363375
)
376+
actual = evaluator.get_applicable_candidates(candidates)
364377
actual_versions = [str(c.version) for c in actual]
365378
assert actual_versions == expected_versions
366379

@@ -370,10 +383,11 @@ def test_make_found_candidates(self):
370383
candidates = [
371384
make_mock_candidate(version) for version in versions
372385
]
373-
evaluator = CandidateEvaluator.create('my-project')
374-
found_candidates = evaluator.make_found_candidates(
375-
candidates, specifier=specifier,
386+
evaluator = CandidateEvaluator.create(
387+
'my-project',
388+
specifier=specifier,
376389
)
390+
found_candidates = evaluator.make_found_candidates(candidates)
377391

378392
assert found_candidates._candidates == candidates
379393
assert found_candidates._evaluator is evaluator
@@ -776,15 +790,19 @@ def test_make_candidate_evaluator(
776790
candidate_prefs=candidate_prefs,
777791
)
778792

793+
specifier = SpecifierSet()
779794
# Pass hashes to check that _hashes is set.
780795
hashes = Hashes({'sha256': [64 * 'a']})
781796
evaluator = finder.make_candidate_evaluator(
782-
'my-project', hashes=hashes,
797+
'my-project',
798+
specifier=specifier,
799+
hashes=hashes,
783800
)
784801
assert evaluator._allow_all_prereleases == allow_all_prereleases
785802
assert evaluator._hashes == hashes
786803
assert evaluator._prefer_binary == prefer_binary
787804
assert evaluator._project_name == 'my-project'
805+
assert evaluator._specifier is specifier
788806
assert evaluator._supported_tags == [('py36', 'none', 'any')]
789807

790808

0 commit comments

Comments
 (0)