Skip to content

Commit 449d268

Browse files
authored
Merge pull request #6661 from cjerdonek/add-selection-prefs-class
Add a SelectionPreferences class
2 parents 974f08d + ae79b5b commit 449d268

File tree

8 files changed

+108
-37
lines changed

8 files changed

+108
-37
lines changed

src/pip/_internal/cli/base_command.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
)
2626
from pip._internal.index import PackageFinder
2727
from pip._internal.locations import running_under_virtualenv
28+
from pip._internal.models.selection_prefs import SelectionPreferences
2829
from pip._internal.models.target_python import TargetPython
2930
from pip._internal.req.constructors import (
3031
install_req_from_editable, install_req_from_line,
@@ -337,6 +338,13 @@ def _build_package_finder(
337338
"Requires-Python" values in links. Defaults to False.
338339
"""
339340
search_scope = make_search_scope(options)
341+
selection_prefs = SelectionPreferences(
342+
allow_yanked=True,
343+
format_control=options.format_control,
344+
allow_all_prereleases=options.pre,
345+
prefer_binary=options.prefer_binary,
346+
ignore_requires_python=ignore_requires_python,
347+
)
340348

341349
target_python = TargetPython(
342350
platform=platform,
@@ -347,12 +355,8 @@ def _build_package_finder(
347355

348356
return PackageFinder.create(
349357
search_scope=search_scope,
350-
allow_yanked=True,
351-
format_control=options.format_control,
358+
selection_prefs=selection_prefs,
352359
trusted_hosts=options.trusted_hosts,
353-
allow_all_prereleases=options.pre,
354360
session=session,
355361
target_python=target_python,
356-
prefer_binary=options.prefer_binary,
357-
ignore_requires_python=ignore_requires_python,
358362
)

src/pip/_internal/commands/list.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pip._internal.cli.cmdoptions import make_search_scope
1212
from pip._internal.exceptions import CommandError
1313
from pip._internal.index import PackageFinder
14+
from pip._internal.models.selection_prefs import SelectionPreferences
1415
from pip._internal.utils.misc import (
1516
dist_is_editable, get_installed_distributions,
1617
)
@@ -117,10 +118,14 @@ def _build_package_finder(self, options, session):
117118
search_scope = make_search_scope(options)
118119

119120
# Pass allow_yanked=False to ignore yanked versions.
120-
return PackageFinder.create(
121-
search_scope=search_scope,
121+
selection_prefs = SelectionPreferences(
122122
allow_yanked=False,
123123
allow_all_prereleases=options.pre,
124+
)
125+
126+
return PackageFinder.create(
127+
search_scope=search_scope,
128+
selection_prefs=selection_prefs,
124129
trusted_hosts=options.trusted_hosts,
125130
session=session,
126131
)

src/pip/_internal/index.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from pip._internal.models.candidate import InstallationCandidate
2727
from pip._internal.models.format_control import FormatControl
2828
from pip._internal.models.link import Link
29+
from pip._internal.models.selection_prefs import SelectionPreferences
2930
from pip._internal.models.target_python import TargetPython
3031
from pip._internal.utils.compat import ipaddress
3132
from pip._internal.utils.logging import indent_log
@@ -649,31 +650,20 @@ def __init__(
649650
def create(
650651
cls,
651652
search_scope, # type: SearchScope
652-
allow_yanked, # type: bool
653-
allow_all_prereleases=False, # type: bool
653+
selection_prefs, # type: SelectionPreferences
654654
trusted_hosts=None, # type: Optional[List[str]]
655-
session=None, # type: Optional[PipSession]
656-
format_control=None, # type: Optional[FormatControl]
655+
session=None, # type: Optional[PipSession]
657656
target_python=None, # type: Optional[TargetPython]
658-
prefer_binary=False, # type: bool
659-
ignore_requires_python=None, # type: Optional[bool]
660657
):
661658
# type: (...) -> PackageFinder
662659
"""Create a PackageFinder.
663660
664-
:param allow_yanked: Whether files marked as yanked (in the sense
665-
of PEP 592) are permitted to be candidates for install.
661+
:param selection_prefs: The candidate selection preferences, as a
662+
SelectionPreferences object.
666663
:param trusted_hosts: Domains not to emit warnings for when not using
667664
HTTPS.
668665
:param session: The Session to use to make requests.
669-
:param format_control: A FormatControl object or None. Used to control
670-
the selection of source packages / binary packages when consulting
671-
the index and links.
672666
:param target_python: The target Python interpreter.
673-
:param prefer_binary: Whether to prefer an old, but valid, binary
674-
dist over a new source dist.
675-
:param ignore_requires_python: Whether to ignore incompatible
676-
"Requires-Python" values in links. Defaults to False.
677667
"""
678668
if session is None:
679669
raise TypeError(
@@ -682,18 +672,18 @@ def create(
682672
)
683673

684674
candidate_evaluator = CandidateEvaluator(
685-
allow_yanked=allow_yanked,
675+
allow_yanked=selection_prefs.allow_yanked,
686676
target_python=target_python,
687-
prefer_binary=prefer_binary,
688-
allow_all_prereleases=allow_all_prereleases,
689-
ignore_requires_python=ignore_requires_python,
677+
prefer_binary=selection_prefs.prefer_binary,
678+
allow_all_prereleases=selection_prefs.allow_all_prereleases,
679+
ignore_requires_python=selection_prefs.ignore_requires_python,
690680
)
691681

692682
return cls(
693683
candidate_evaluator=candidate_evaluator,
694684
search_scope=search_scope,
695685
session=session,
696-
format_control=format_control,
686+
format_control=selection_prefs.format_control,
697687
trusted_hosts=trusted_hosts,
698688
)
699689

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2+
3+
if MYPY_CHECK_RUNNING:
4+
from typing import Optional
5+
from pip._internal.models.format_control import FormatControl
6+
7+
8+
class SelectionPreferences(object):
9+
10+
"""
11+
Encapsulates the candidate selection preferences for downloading
12+
and installing files.
13+
"""
14+
15+
# Don't include an allow_yanked default value to make sure each call
16+
# site considers whether yanked releases are allowed. This also causes
17+
# that decision to be made explicit in the calling code, which helps
18+
# people when reading the code.
19+
def __init__(
20+
self,
21+
allow_yanked, # type: bool
22+
allow_all_prereleases=False, # type: bool
23+
format_control=None, # type: Optional[FormatControl]
24+
prefer_binary=False, # type: bool
25+
ignore_requires_python=None, # type: Optional[bool]
26+
):
27+
# type: (...) -> None
28+
"""Create a SelectionPreferences object.
29+
30+
:param allow_yanked: Whether files marked as yanked (in the sense
31+
of PEP 592) are permitted to be candidates for install.
32+
:param format_control: A FormatControl object or None. Used to control
33+
the selection of source packages / binary packages when consulting
34+
the index and links.
35+
:param prefer_binary: Whether to prefer an old, but valid, binary
36+
dist over a new source dist.
37+
:param ignore_requires_python: Whether to ignore incompatible
38+
"Requires-Python" values in links. Defaults to False.
39+
"""
40+
if ignore_requires_python is None:
41+
ignore_requires_python = False
42+
43+
self.allow_yanked = allow_yanked
44+
self.allow_all_prereleases = allow_all_prereleases
45+
self.format_control = format_control
46+
self.prefer_binary = prefer_binary
47+
self.ignore_requires_python = ignore_requires_python

src/pip/_internal/utils/outdated.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from pip._internal.cli.cmdoptions import make_search_scope
1313
from pip._internal.index import PackageFinder
14+
from pip._internal.models.selection_prefs import SelectionPreferences
1415
from pip._internal.utils.compat import WINDOWS
1516
from pip._internal.utils.filesystem import check_path_owner
1617
from pip._internal.utils.misc import ensure_dir, get_installed_version
@@ -127,10 +128,14 @@ def pip_version_check(session, options):
127128

128129
# Pass allow_yanked=False so we don't suggest upgrading to a
129130
# yanked version.
130-
finder = PackageFinder.create(
131-
search_scope=search_scope,
131+
selection_prefs = SelectionPreferences(
132132
allow_yanked=False,
133133
allow_all_prereleases=False, # Explicitly set to False
134+
)
135+
136+
finder = PackageFinder.create(
137+
search_scope=search_scope,
138+
selection_prefs=selection_prefs,
134139
trusted_hosts=options.trusted_hosts,
135140
session=session,
136141
)

tests/lib/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
import pytest
1414
from scripttest import FoundDir, TestFileEnvironment
1515

16-
from pip._internal.models.search_scope import SearchScope
17-
from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX
1816
from pip._internal.download import PipSession
1917
from pip._internal.index import PackageFinder
18+
from pip._internal.models.search_scope import SearchScope
19+
from pip._internal.models.selection_prefs import SelectionPreferences
20+
from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX
2021
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2122
from tests.lib.path import Path, curdir
2223

@@ -101,11 +102,14 @@ def make_test_finder(
101102
find_links=find_links,
102103
index_urls=index_urls,
103104
)
105+
selection_prefs = SelectionPreferences(
106+
allow_yanked=True,
107+
allow_all_prereleases=allow_all_prereleases,
108+
)
104109

105110
return PackageFinder.create(
106111
search_scope=search_scope,
107-
allow_yanked=True,
108-
allow_all_prereleases=allow_all_prereleases,
112+
selection_prefs=selection_prefs,
109113
trusted_hosts=trusted_hosts,
110114
session=session,
111115
target_python=target_python,

tests/unit/test_build_env.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ def run_with_build_env(script, setup_script_contents,
2525
from pip._internal.download import PipSession
2626
from pip._internal.index import PackageFinder
2727
from pip._internal.models.search_scope import SearchScope
28+
from pip._internal.models.selection_prefs import (
29+
SelectionPreferences
30+
)
2831
2932
search_scope = SearchScope.create([%r], [])
33+
selection_prefs = SelectionPreferences(
34+
allow_yanked=True,
35+
)
3036
finder = PackageFinder.create(
3137
search_scope,
32-
allow_yanked=True,
38+
selection_prefs=selection_prefs,
3339
session=PipSession(),
3440
)
3541
build_env = BuildEnvironment()

tests/unit/test_index.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
)
1414
from pip._internal.models.candidate import InstallationCandidate
1515
from pip._internal.models.search_scope import SearchScope
16+
from pip._internal.models.selection_prefs import SelectionPreferences
1617
from pip._internal.models.target_python import TargetPython
1718
from tests.lib import CURRENT_PY_VERSION_INFO, make_test_finder
1819

@@ -307,9 +308,12 @@ def test_create__allow_yanked(self, allow_yanked):
307308
Test that allow_yanked is passed to CandidateEvaluator.
308309
"""
309310
search_scope = SearchScope([], [])
311+
selection_prefs = SelectionPreferences(
312+
allow_yanked=allow_yanked,
313+
)
310314
finder = PackageFinder.create(
311315
search_scope=search_scope,
312-
allow_yanked=allow_yanked,
316+
selection_prefs=selection_prefs,
313317
session=object(),
314318
)
315319
evaluator = finder.candidate_evaluator
@@ -320,10 +324,13 @@ def test_create__target_python(self):
320324
Test that target_python is passed to CandidateEvaluator as is.
321325
"""
322326
search_scope = SearchScope([], [])
327+
selection_prefs = SelectionPreferences(
328+
allow_yanked=True,
329+
)
323330
target_python = TargetPython(py_version_info=(3, 7, 3))
324331
finder = PackageFinder.create(
325332
search_scope=search_scope,
326-
allow_yanked=True,
333+
selection_prefs=selection_prefs,
327334
session=object(),
328335
target_python=target_python,
329336
)
@@ -407,9 +414,12 @@ def test_iter_secure_origins__none_trusted_hosts(self):
407414
# Use PackageFinder.create() rather than make_test_finder()
408415
# to make sure we're really passing trusted_hosts=None.
409416
search_scope = SearchScope([], [])
417+
selection_prefs = SelectionPreferences(
418+
allow_yanked=True,
419+
)
410420
finder = PackageFinder.create(
411421
search_scope=search_scope,
412-
allow_yanked=True,
422+
selection_prefs=selection_prefs,
413423
trusted_hosts=None,
414424
session=object(),
415425
)

0 commit comments

Comments
 (0)