diff --git a/news/12918.removal.rst b/news/12918.removal.rst new file mode 100644 index 00000000000..c5a52cf66e1 --- /dev/null +++ b/news/12918.removal.rst @@ -0,0 +1 @@ +Deprecate wheel filenames that are not compliant with PEP 440. diff --git a/src/pip/_internal/models/wheel.py b/src/pip/_internal/models/wheel.py index 36d4d2e785c..63db978f1f5 100644 --- a/src/pip/_internal/models/wheel.py +++ b/src/pip/_internal/models/wheel.py @@ -8,6 +8,7 @@ from pip._vendor.packaging.tags import Tag from pip._internal.exceptions import InvalidWheelFilename +from pip._internal.utils.deprecation import deprecated class Wheel: @@ -29,9 +30,25 @@ def __init__(self, filename: str) -> None: raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.") self.filename = filename self.name = wheel_info.group("name").replace("_", "-") - # we'll assume "_" means "-" due to wheel naming scheme - # (https://github.com/pypa/pip/issues/1150) - self.version = wheel_info.group("ver").replace("_", "-") + _version = wheel_info.group("ver") + if "_" in _version: + deprecated( + reason=( + f"Wheel filename {filename!r} uses an invalid filename format, " + f"as the version part {_version!r} is not correctly normalised, " + "and contains an underscore character. Future versions of pip may " + "fail to recognise this wheel." + ), + replacement=( + "rename the wheel to use a correctly normalised version part " + "(this may require updating the version in the project metadata)" + ), + gone_in="25.1", + issue=12914, + ) + _version = _version.replace("_", "-") + + self.version = _version self.build_tag = wheel_info.group("build") self.pyversions = wheel_info.group("pyver").split(".") self.abis = wheel_info.group("abi").split(".") diff --git a/tests/unit/test_models_wheel.py b/tests/unit/test_models_wheel.py index c06525e089e..ee4d88c744a 100644 --- a/tests/unit/test_models_wheel.py +++ b/tests/unit/test_models_wheel.py @@ -3,7 +3,7 @@ from pip._internal.exceptions import InvalidWheelFilename from pip._internal.models.wheel import Wheel -from pip._internal.utils import compatibility_tags +from pip._internal.utils import compatibility_tags, deprecation class TestWheelFile: @@ -175,5 +175,6 @@ def test_version_underscore_conversion(self) -> None: Test that we convert '_' to '-' for versions parsed out of wheel filenames """ - w = Wheel("simple-0.1_1-py2-none-any.whl") + with pytest.warns(deprecation.PipDeprecationWarning): + w = Wheel("simple-0.1_1-py2-none-any.whl") assert w.version == "0.1-1"