Repository: pypa/pip
File: src/pip/_internal/models/wheel.py (Python)

Code before:
class Wheel:
    """A wheel file"""

    wheel_file_re = re.compile(
        r"""^(?P<namever>(?P<name>[^\s-]+?)-(?P<ver>[^\s-]*?))
        ((-(?P<build>\d[^-]*?))?-(?P<pyver>[^\s-]+?)-(?P<abi>[^\s-]+?)-(?P<plat>[^\s-]+?)
        \.whl|\.dist-info)$""",
        re.VERBOSE,
    )

    def __init__(self, filename: str) -> None:
        """
        :raises InvalidWheelFilename: when the filename is invalid for a wheel
        """
        wheel_info = self.wheel_file_re.match(filename)
        if not wheel_info:
            raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.")
        self.filename = filename
        self.name = wheel_info.group("name").replace("_", "-")
        _version = wheel_info.group("ver")
        if "_" in _version:
            _version = _version.replace("_", "-")

            try:
                parse_wheel_filename(filename)
            except (PackagingInvalidWheelName, InvalidVersion):
                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 will 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=12938,
                )

        self.version = _version
        self.build_tag = wheel_info.group("build")
        self.pyversions = wheel_info.group("pyver").split(".")
        self.abis = wheel_info.group("abi").split(".")
        self.plats = wheel_info.group("plat").split(".")

        # All the tag combinations from this file
        self.file_tags = {
            Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats

Review comment (suggestion):
By just reading the code here, it's not obvious that all wheel filename parsing errors here are guaranteed to relate to an invalid version part.

Would it make sense to catch the two exception separately with a slightly different deprecation message?

Or is there a guarantee here that all exceptions are due to the version part? In that case a little comment explaining that might be useful.

Code after:
class Wheel:
    """A wheel file"""

    wheel_file_re = re.compile(
        r"""^(?P<namever>(?P<name>[^\s-]+?)-(?P<ver>[^\s-]*?))
        ((-(?P<build>\d[^-]*?))?-(?P<pyver>[^\s-]+?)-(?P<abi>[^\s-]+?)-(?P<plat>[^\s-]+?)
        \.whl|\.dist-info)$""",
        re.VERBOSE,
    )

    def __init__(self, filename: str) -> None:
        """
        :raises InvalidWheelFilename: when the filename is invalid for a wheel
        """
        wheel_info = self.wheel_file_re.match(filename)
        if not wheel_info:
            raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.")
        self.filename = filename
        self.name = wheel_info.group("name").replace("_", "-")
        _version = wheel_info.group("ver")
        if "_" in _version:
            try:
                parse_wheel_filename(filename)
            except InvalidVersion as e:
                deprecated(
                    reason=(
                        f"Wheel filename version part {_version!r} is not correctly "
                        "normalised, and contained an underscore character in the "
                        "version part. Future versions of pip will fail to recognise "
                        f"this wheel and report the error: {e.args[0]}."
                    ),
                    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=12938,
                )
            except PackagingInvalidWheelName as e:
                deprecated(
                    reason=(
                        f"The wheel filename {filename!r} is not correctly normalised. "
                        "Future versions of pip will fail to recognise this wheel. "
                        f"and report the error: {e.args[0]}."
                    ),
                    replacement=(
                        "rename the wheel to use a correctly normalised "
                        "name (this may require updating the version in "
                        "the project metadata)"
                    ),