python-poetry/poetry · error · InvalidWheelNameError

is not a valid wheel filename.

Error message

{filename} is not a valid wheel filename.

What it means

Wheel.__init__ matches the filename against wheel_file_re (PEP 427 layout: {name}-{ver}(-{build})?-{pyver}-{abi}-{plat}.whl). If the regex does not match it raises InvalidWheelNameError. The filename must contain all five required dash-separated tag fields plus the .whl suffix.

Solutions

  1. Verify the filename conforms to PEP 427 (all of name, version, python tag, abi tag, platform tag, and .whl).
  2. Re-download the wheel from the publisher or rebuild it with `pip wheel`/`python -m build`.
  3. Do not feed sdist/source paths to Wheel(); use Wheel only for .whl files.

Example fix

# before
Wheel('requests-2.31.whl')          # missing tag fields -> InvalidWheelNameError
# after
Wheel('requests-2.31.0-py3-none-any.whl')
Defensive patterns

Strategy: validation

Validate before calling

from poetry.utils.patterns import wheel_file_re

def is_valid_wheel_filename(filename: str) -> bool:
    return wheel_file_re.match(filename) is not None

Type guard

from poetry.utils.patterns import wheel_file_re

def is_wheel_filename(filename: str) -> bool:
    return filename.endswith('.whl') and wheel_file_re.match(filename) is not None

Try / catch

from poetry.utils.wheel import InvalidWheelNameError, Wheel
try:
    w = Wheel(filename)
except InvalidWheelNameError:
    # not a wheel; handle as sdist/source or reject
    raise

Prevention

When it happens

Trigger: Constructing Wheel('foo.txt'), Wheel('foo-1.0.tar.gz') (sdist), or a wheel missing tag fields like 'foo-1.0.whl' or 'foo-1.0-py3-none-any' (no extension).

Common situations: Passing a non-wheel filename to Wheel; a truncated/renamed download; a wheel produced by non-standard tooling that omits the build tag delimiter; filename with unescaped dashes confusing the regex.

Related errors


AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04). Data as JSON: /api/errors/22e375c695b9cb69. Report an issue: GitHub.

Appendix: source

Thrown at src/poetry/utils/wheel.py:27

from poetry.utils.patterns import wheel_file_re


if TYPE_CHECKING:
    from poetry.utils.env import Env


logger = logging.getLogger(__name__)


class InvalidWheelNameError(Exception):
    pass


class Wheel:
    def __init__(self, filename: str) -> None:
        wheel_info = wheel_file_re.match(filename)
        if not wheel_info:
            raise InvalidWheelNameError(f"{filename} is not a valid wheel filename.")

        self.filename = filename
        self.name = wheel_info.group("name").replace("_", "-")
        self.version = wheel_info.group("ver").replace("_", "-")
        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(".")

        self.tags = {
            Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats
        }

    def get_minimum_supported_index(self, tags: list[Tag]) -> int | None:
        indexes = [tags.index(t) for t in self.tags if t in tags]

        return min(indexes) if indexes else None

View on GitHub (pinned to 92b74dcfe3)