mirror of https://github.com/pypa/pip
Add a --prefer-binary flag. (#5370)
The flag makes pip prefer an older but valid binary distributions over a newer source distributions. Fixes #3785.
This commit is contained in:
parent
df45aafd15
commit
d67d98dd91
|
@ -0,0 +1 @@
|
|||
Introduce a new --prefer-binary flag, to prefer older wheels over newer source packages.
|
|
@ -370,4 +370,5 @@ class RequirementCommand(Command):
|
|||
versions=python_versions,
|
||||
abi=abi,
|
||||
implementation=implementation,
|
||||
prefer_binary=options.prefer_binary,
|
||||
)
|
||||
|
|
|
@ -406,6 +406,16 @@ def only_binary():
|
|||
)
|
||||
|
||||
|
||||
def prefer_binary():
|
||||
return Option(
|
||||
"--prefer-binary",
|
||||
dest="prefer_binary",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Prefer older binary packages over newer source packages."
|
||||
)
|
||||
|
||||
|
||||
cache_dir = partial(
|
||||
Option,
|
||||
"--cache-dir",
|
||||
|
|
|
@ -52,6 +52,7 @@ class DownloadCommand(RequirementCommand):
|
|||
cmd_opts.add_option(cmdoptions.global_options())
|
||||
cmd_opts.add_option(cmdoptions.no_binary())
|
||||
cmd_opts.add_option(cmdoptions.only_binary())
|
||||
cmd_opts.add_option(cmdoptions.prefer_binary())
|
||||
cmd_opts.add_option(cmdoptions.src())
|
||||
cmd_opts.add_option(cmdoptions.pre())
|
||||
cmd_opts.add_option(cmdoptions.no_clean())
|
||||
|
|
|
@ -183,6 +183,7 @@ class InstallCommand(RequirementCommand):
|
|||
|
||||
cmd_opts.add_option(cmdoptions.no_binary())
|
||||
cmd_opts.add_option(cmdoptions.only_binary())
|
||||
cmd_opts.add_option(cmdoptions.prefer_binary())
|
||||
cmd_opts.add_option(cmdoptions.no_clean())
|
||||
cmd_opts.add_option(cmdoptions.require_hashes())
|
||||
cmd_opts.add_option(cmdoptions.progress_bar())
|
||||
|
|
|
@ -57,6 +57,7 @@ class WheelCommand(RequirementCommand):
|
|||
)
|
||||
cmd_opts.add_option(cmdoptions.no_binary())
|
||||
cmd_opts.add_option(cmdoptions.only_binary())
|
||||
cmd_opts.add_option(cmdoptions.prefer_binary())
|
||||
cmd_opts.add_option(
|
||||
'--build-option',
|
||||
dest='build_options',
|
||||
|
|
|
@ -108,7 +108,8 @@ class PackageFinder(object):
|
|||
def __init__(self, find_links, index_urls, allow_all_prereleases=False,
|
||||
trusted_hosts=None, process_dependency_links=False,
|
||||
session=None, format_control=None, platform=None,
|
||||
versions=None, abi=None, implementation=None):
|
||||
versions=None, abi=None, implementation=None,
|
||||
prefer_binary=False):
|
||||
"""Create a PackageFinder.
|
||||
|
||||
:param format_control: A FormatControl object or None. Used to control
|
||||
|
@ -176,6 +177,9 @@ class PackageFinder(object):
|
|||
impl=implementation,
|
||||
)
|
||||
|
||||
# Do we prefer old, but valid, binary dist over new source dist
|
||||
self.prefer_binary = prefer_binary
|
||||
|
||||
# If we don't have TLS enabled, then WARN if anyplace we're looking
|
||||
# relies on TLS.
|
||||
if not HAS_TLS:
|
||||
|
@ -275,12 +279,14 @@ class PackageFinder(object):
|
|||
1. existing installs
|
||||
2. wheels ordered via Wheel.support_index_min(self.valid_tags)
|
||||
3. source archives
|
||||
If prefer_binary was set, then all wheels are sorted above sources.
|
||||
Note: it was considered to embed this logic into the Link
|
||||
comparison operators, but then different sdist links
|
||||
with the same version, would have to be considered equal
|
||||
"""
|
||||
support_num = len(self.valid_tags)
|
||||
build_tag = tuple()
|
||||
binary_preference = 0
|
||||
if candidate.location.is_wheel:
|
||||
# can raise InvalidWheelFilename
|
||||
wheel = Wheel(candidate.location.filename)
|
||||
|
@ -289,6 +295,8 @@ class PackageFinder(object):
|
|||
"%s is not a supported wheel for this platform. It "
|
||||
"can't be sorted." % wheel.filename
|
||||
)
|
||||
if self.prefer_binary:
|
||||
binary_preference = 1
|
||||
pri = -(wheel.support_index_min(self.valid_tags))
|
||||
if wheel.build_tag is not None:
|
||||
match = re.match(r'^(\d+)(.*)$', wheel.build_tag)
|
||||
|
@ -296,7 +304,7 @@ class PackageFinder(object):
|
|||
build_tag = (int(build_tag_groups[0]), build_tag_groups[1])
|
||||
else: # sdist
|
||||
pri = -(support_num)
|
||||
return (candidate.version, build_tag, pri)
|
||||
return (binary_preference, candidate.version, build_tag, pri)
|
||||
|
||||
def _validate_secure_origin(self, logger, location):
|
||||
# Determine if this url used a secure transport mechanism
|
||||
|
|
|
@ -602,3 +602,60 @@ def test_download_exit_status_code_when_blank_requirements_file(script):
|
|||
"""
|
||||
script.scratch_path.join("blank.txt").write("\n")
|
||||
script.pip('download', '-r', 'blank.txt')
|
||||
|
||||
|
||||
def test_download_prefer_binary_when_tarball_higher_than_wheel(script, data):
|
||||
fake_wheel(data, 'source-0.8-py2.py3-none-any.whl')
|
||||
result = script.pip(
|
||||
'download',
|
||||
'--prefer-binary',
|
||||
'--no-index',
|
||||
'-f', data.packages,
|
||||
'-d', '.', 'source'
|
||||
)
|
||||
assert (
|
||||
Path('scratch') / 'source-0.8-py2.py3-none-any.whl'
|
||||
in result.files_created
|
||||
)
|
||||
assert (
|
||||
Path('scratch') / 'source-1.0.tar.gz'
|
||||
not in result.files_created
|
||||
)
|
||||
|
||||
|
||||
def test_download_prefer_binary_when_wheel_doesnt_satisfy_req(script, data):
|
||||
fake_wheel(data, 'source-0.8-py2.py3-none-any.whl')
|
||||
script.scratch_path.join("test-req.txt").write(textwrap.dedent("""
|
||||
source>0.9
|
||||
"""))
|
||||
|
||||
result = script.pip(
|
||||
'download',
|
||||
'--prefer-binary',
|
||||
'--no-index',
|
||||
'-f', data.packages,
|
||||
'-d', '.',
|
||||
'-r', script.scratch_path / 'test-req.txt'
|
||||
)
|
||||
assert (
|
||||
Path('scratch') / 'source-1.0.tar.gz'
|
||||
in result.files_created
|
||||
)
|
||||
assert (
|
||||
Path('scratch') / 'source-0.8-py2.py3-none-any.whl'
|
||||
not in result.files_created
|
||||
)
|
||||
|
||||
|
||||
def test_download_prefer_binary_when_only_tarball_exists(script, data):
|
||||
result = script.pip(
|
||||
'download',
|
||||
'--prefer-binary',
|
||||
'--no-index',
|
||||
'-f', data.packages,
|
||||
'-d', '.', 'source'
|
||||
)
|
||||
assert (
|
||||
Path('scratch') / 'source-1.0.tar.gz'
|
||||
in result.files_created
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue