mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Deprecate requirements format "base>=1.0[extra]"
This requirements format does not conform to PEP-508. Currently the extras specified like this work by accident (because _strip_extras() also parses them). The version checks end up being done with a misparsed version '1.0[extra]' -- this is not changed in this commit. Add deprecation warning and fix the corresponding resolver test. Add a command line test. Note that we really only check that the Requirement has SpecifierSet with a specifier that ends in a ']'. A valid version number cannot contain ']' and no wheels currently on pypi have versions ending in ']'.
This commit is contained in:
parent
8bf5731b84
commit
76b20d738e
4 changed files with 60 additions and 2 deletions
1
news/8288.removal
Normal file
1
news/8288.removal
Normal file
|
@ -0,0 +1 @@
|
|||
Add deprecation warning for invalid requirements format "base>=1.0[extra]"
|
|
@ -23,6 +23,7 @@ from pip._internal.models.link import Link
|
|||
from pip._internal.models.wheel import Wheel
|
||||
from pip._internal.pyproject import make_pyproject_path
|
||||
from pip._internal.req.req_install import InstallRequirement
|
||||
from pip._internal.utils.deprecation import deprecated
|
||||
from pip._internal.utils.filetypes import ARCHIVE_EXTENSIONS
|
||||
from pip._internal.utils.misc import is_installable_dir, splitext
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
@ -370,6 +371,17 @@ def parse_req_from_line(name, line_source):
|
|||
if add_msg:
|
||||
msg += '\nHint: {}'.format(add_msg)
|
||||
raise InstallationError(msg)
|
||||
else:
|
||||
# Deprecate extras after specifiers: "name>=1.0[extras]"
|
||||
# This currently works by accident because _strip_extras() parses
|
||||
# any extras in the end of the string and those are saved in
|
||||
# RequirementParts
|
||||
for spec in req.specifier:
|
||||
spec_str = str(spec)
|
||||
if spec_str.endswith(']'):
|
||||
msg = "Extras after version '{}'.".format(spec_str)
|
||||
replace = "moving the extras before version specifiers"
|
||||
deprecated(msg, replacement=replace, gone_in="21.0")
|
||||
else:
|
||||
req = None
|
||||
|
||||
|
|
|
@ -104,6 +104,27 @@ def test_nonexistent_options_listed_in_order(script, data):
|
|||
assert matches == ['nonexistent', 'nope']
|
||||
|
||||
|
||||
def test_install_deprecated_extra(script, data):
|
||||
"""
|
||||
Warn about deprecated order of specifiers and extras.
|
||||
|
||||
Test uses a requirements file to avoid a testing issue where
|
||||
the specifier gets interpreted as shell redirect.
|
||||
"""
|
||||
script.scratch_path.joinpath("requirements.txt").write_text(
|
||||
"requires_simple_extra>=0.1[extra]"
|
||||
)
|
||||
simple = script.site_packages / 'simple'
|
||||
|
||||
result = script.pip(
|
||||
'install', '--no-index', '--find-links=' + data.find_links,
|
||||
'-r', script.scratch_path / 'requirements.txt', expect_stderr=True,
|
||||
)
|
||||
|
||||
result.did_create(simple)
|
||||
assert ("DEPRECATION: Extras after version" in result.stderr)
|
||||
|
||||
|
||||
def test_install_special_extra(script):
|
||||
# Check that uppercase letters and '-' are dealt with
|
||||
# make a dummy project
|
||||
|
|
|
@ -200,8 +200,6 @@ def test_new_resolver_ignore_dependencies(script):
|
|||
[
|
||||
"base[add]",
|
||||
"base[add] >= 0.1.0",
|
||||
# Non-standard syntax. To deprecate, see pypa/pip#8288.
|
||||
"base >= 0.1.0[add]",
|
||||
],
|
||||
)
|
||||
def test_new_resolver_installs_extras(tmpdir, script, root_dep):
|
||||
|
@ -228,6 +226,32 @@ def test_new_resolver_installs_extras(tmpdir, script, root_dep):
|
|||
assert_installed(script, base="0.1.0", dep="0.1.0")
|
||||
|
||||
|
||||
def test_new_resolver_installs_extras_deprecated(tmpdir, script):
|
||||
req_file = tmpdir.joinpath("requirements.txt")
|
||||
req_file.write_text("base >= 0.1.0[add]")
|
||||
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
"base",
|
||||
"0.1.0",
|
||||
extras={"add": ["dep"]},
|
||||
)
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
"dep",
|
||||
"0.1.0",
|
||||
)
|
||||
result = script.pip(
|
||||
"install", "--use-feature=2020-resolver",
|
||||
"--no-cache-dir", "--no-index",
|
||||
"--find-links", script.scratch_path,
|
||||
"-r", req_file,
|
||||
expect_stderr=True
|
||||
)
|
||||
assert "DEPRECATION: Extras after version" in result.stderr
|
||||
assert_installed(script, base="0.1.0", dep="0.1.0")
|
||||
|
||||
|
||||
def test_new_resolver_installs_extras_warn_missing(script):
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
|
|
Loading…
Reference in a new issue