{"record":{"id":"644c4d38196042d5","repo":"pypa/pip","slug":"invalid-wheel-filename-wrong-number-of-parts-f","errorCode":null,"errorMessage":"Invalid wheel filename (wrong number of parts): {filename!r}","messagePattern":"Invalid wheel filename \\(wrong number of parts\\): (.+?)","errorType":"validation","errorClass":"InvalidWheelFilename","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/utils.py","lineNumber":263,"sourceCode":"       Raises :class:`InvalidWheelFilename` when the version component is invalid.\n\n    .. versionadded:: 26.1\n       The *validate_order* parameter.\n\n    .. versionchanged:: 26.3\n       Raises :class:`InvalidWheelFilename` when an interpreter component is\n       not an identifier, a tag set component is empty, or the project name is\n       empty.\n    \"\"\"\n    if not filename.endswith(\".whl\"):\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (extension must be '.whl'): {filename!r}\"\n        )\n\n    filename = filename[:-4]\n    dashes = filename.count(\"-\")\n    if dashes not in (4, 5):\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (wrong number of parts): {filename!r}\"\n        )\n\n    parts = filename.split(\"-\", dashes - 2)\n    name_part = parts[0]\n    # See PEP 427 for the rules on escaping the project name.\n    if \"__\" in name_part or _wheel_name_regex.match(name_part) is None:\n        raise InvalidWheelFilename(f\"Invalid project name: {filename!r}\")\n    name = canonicalize_name(name_part)\n\n    try:\n        version = Version(parts[1])\n    except InvalidVersion as e:\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (invalid version): {filename!r}\"\n        ) from e\n\n    if dashes == 5:","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/utils.py#L245-L281","documentation":"Raised by parse_wheel_filename() after stripping '.whl', when the remaining stem does not contain exactly 4 or 5 dashes (utils.py:262). A valid wheel stem is {name}-{version}-[{build}-]{pythontag}-{abitag}-{platformtag}: 4 dashes without a build tag, 5 with one. Any other dash count means the filename is structurally malformed.","triggerScenarios":"A wheel filename with a missing tag component (e.g. 'foo-1.0-py3-none.whl' has only 3 dashes), or one with extra unescaped dashes that inflate the part count beyond 5.","commonSituations":"Manually constructed wheel filenames with formatting errors, a project name containing an unescaped hyphen (should be '_' per PEP 427), or a platform tag that itself contains a dash splitting the count incorrectly.","solutions":["Ensure the stem follows the pattern {name}-{version}-[{build}-]{pythontag}-{abitag}-{platformtag}.","Replace hyphens in the project name with underscores when embedding it in a wheel filename.","Verify all three tag components (python, abi, platform) are present."],"exampleFix":"// before\nparse_wheel_filename('foo-1.0-py3-none.whl')  // missing platform tag, 3 dashes\n// after\nparse_wheel_filename('foo-1.0-py3-none-any.whl')","handlingStrategy":"validation","validationCode":"def safe_parse_wheel(filename: str):\n    if not filename.endswith(\".whl\"):\n        raise ValueError(f\"Not a wheel: {filename!r}\")\n    stem = filename[:-4]\n    if stem.count(\"-\") not in (4, 5):\n        raise ValueError(f\"Wheel stem must have 4 or 5 dashes: {filename!r}\")\n    return parse_wheel_filename(filename)","typeGuard":"def has_valid_wheel_dash_count(filename: str) -> bool:\n    if not isinstance(filename, str) or not filename.endswith(\".whl\"):\n        return False\n    return filename[:-4].count(\"-\") in (4, 5)","tryCatchPattern":"from packaging.utils import InvalidWheelFilename\n\ntry:\n    parse_wheel_filename(filename)\nexcept InvalidWheelFilename as e:\n    if \"wrong number of parts\" in str(e):\n        logger.error(\"Malformed wheel structure: %s\", filename)\n    raise","preventionTips":["Verify the stem has exactly 4 or 5 dashes before parsing","Escape dashes in project names as single underscores","Ensure all three tag components are present"],"tags":["wheel","filename","packaging","pep427"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}