{"id":"5a5b4a0ab47fd10b","repo":"pypa/pip","slug":"metadata-1-2-mandates-pep-440-version-but-dist-v","errorCode":null,"errorMessage":"Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} is not","messagePattern":"Metadata 1\\.2 mandates PEP 440 version, but (.+?) is not","errorType":"exception","errorClass":"UnsupportedWheel","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/wheel_builder.py","lineNumber":116,"sourceCode":"            f\"got {w.name!r}\",\n        )\n    dist = get_wheel_distribution(FilesystemWheel(wheel_path), canonical_name)\n    dist_verstr = str(dist.version)\n    if canonicalize_version(dist_verstr) != canonicalize_version(w.version):\n        raise InvalidWheelFilename(\n            f\"Wheel has unexpected file name: expected {dist_verstr!r}, \"\n            f\"got {w.version!r}\",\n        )\n    metadata_version_value = dist.metadata_version\n    if metadata_version_value is None:\n        raise UnsupportedWheel(\"Missing Metadata-Version\")\n    try:\n        metadata_version = Version(metadata_version_value)\n    except InvalidVersion:\n        msg = f\"Invalid Metadata-Version: {metadata_version_value}\"\n        raise UnsupportedWheel(msg)\n    if metadata_version >= Version(\"1.2\") and not isinstance(dist.version, Version):\n        raise UnsupportedWheel(\n            f\"Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} is not\"\n        )\n\n\ndef _build_one(\n    req: InstallRequirement,\n    output_dir: str,\n    verify: bool,\n    editable: bool,\n) -> str | None:\n    \"\"\"Build one wheel.\n\n    :return: The filename of the built wheel, or None if the build failed.\n    \"\"\"\n    artifact = \"editable\" if editable else \"wheel\"\n    try:\n        ensure_dir(output_dir)\n    except OSError as e:","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/wheel_builder.py#L98-L134","documentation":"Raised by `_verify_one` when the wheel declares `Metadata-Version >= 1.2` (which mandates a PEP 440 compliant version string) but the distribution's version object is not a `pip._vendor.packaging.version.Version` (i.e. it is an `EpochVersion`/Legacy/invalid form). PEP 345/426/PEP 440 require versions in metadata >= 1.2 to be strict PEP 440; otherwise the wheel is considered unsupported.","triggerScenarios":"`metadata_version >= Version('1.2')` and `not isinstance(dist.version, Version)` in `_verify_one`. Happens when a project declares `Metadata-Version: 1.2` (or higher) but its version string is non-PEP-440 (e.g. `1.0-alpha`, `1.0.dev1x`, legacy `1.0-1`).","commonSituations":"Projects with hand-written version strings not following PEP 440 (e.g. `1.0rc`, `1.0.0.beta`, dashes instead of PEP 440 separators); upgrading Metadata-Version without fixing the version; legacy packages re-packaged with modern metadata.","solutions":["Rewrite the version string to be PEP 440 compliant: `1.0a1`, `1.0rc1`, `1.0.post1`, `1.0.dev1` (use dots not dashes, no leading `v`).","If you must keep a non-PEP 440 version, you cannot declare `Metadata-Version >= 1.2`; but the right fix is to make the version compliant.","Use `from packaging.version import Version; Version(your_version)` locally to validate before building."],"exampleFix":"# before\n[project]\nname = \"mypkg\"\nversion = \"1.0-rc1\"        # not PEP 440\n# METADATA: Metadata-Version: 2.1\n\n# after\n[project]\nname = \"mypkg\"\nversion = \"1.0rc1\"        # PEP 440 compliant","handlingStrategy":"validation","validationCode":"from packaging.version import Version, InvalidVersion\n\ndef assert_pep440_version(version: str) -> None:\n    try:\n        Version(version)\n    except InvalidVersion:\n        raise ValueError(f\"{version!r} is not a PEP 440 version\")\n\n# before building:\nassert_pep440_version(project_version)","typeGuard":"from packaging.version import Version, InvalidVersion\n\ndef is_pep440(v: str) -> bool:\n    try:\n        Version(v)\n        return True\n    except InvalidVersion:\n        return False","tryCatchPattern":"from pip._internal.exceptions import UnsupportedWheel\ntry:\n    _verify_one(req, wheel_path)\nexcept UnsupportedWheel as e:\n    if \"mandates PEP 440\" in str(e):\n        # fix version string in pyproject/setup\n        ...","preventionTips":["Author versions per PEP 440 (`1.0a1`, `1.0rc1`, `1.0.post1`, `1.0.dev1`).","Validate `Version(your_version)` in CI before building.","Avoid dashes/`v` prefix in version literals."],"tags":["wheel","packaging","pep440","versioning","metadata"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}