{"record":{"id":"f65982e3e6d8cf47","repo":"pypa/pip","slug":"invalid-sdist-filename-invalid-version-filenam","errorCode":null,"errorMessage":"Invalid sdist filename (invalid version): {filename!r}","messagePattern":"Invalid sdist filename \\(invalid version\\): (.+?)","errorType":"validation","errorClass":"InvalidSdistFilename","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/utils.py","lineNumber":366,"sourceCode":"            f\" {filename!r}\"\n        )\n\n    # We are requiring a PEP 440 version, which cannot contain dashes,\n    # so we split on the last dash.\n    name_part, sep, version_part = file_stem.rpartition(\"-\")\n    if not sep:\n        raise InvalidSdistFilename(f\"Invalid sdist filename: {filename!r}\")\n    if not name_part:\n        raise InvalidSdistFilename(\n            f\"Invalid sdist filename (empty project name): {filename!r}\"\n        )\n\n    name = canonicalize_name(name_part)\n\n    try:\n        version = Version(version_part)\n    except InvalidVersion as e:\n        raise InvalidSdistFilename(\n            f\"Invalid sdist filename (invalid version): {filename!r}\"\n        ) from e\n\n    return (name, version)\n","sourceCodeStart":348,"sourceCodeEnd":371,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/utils.py#L348-L371","documentation":"Raised by parse_sdist_filename() when the version portion (after the last dash in the stem) cannot be parsed by Version() (utils.py:363-368). The inner InvalidVersion is caught and re-raised as InvalidSdistFilename. The version must conform to PEP 440.","triggerScenarios":"An sdist filename where the version segment is not a valid PEP 440 version, e.g. parse_sdist_filename('foo-latest.tar.gz') where 'latest' fails Version() parsing.","commonSituations":"A version like 'latest', 'snapshot', or a non-numeric tag, or a version scheme that deviates from PEP 440. Also seen when the filename has a name containing a dash so rpartition splits at the wrong position.","solutions":["Verify the version segment (after the last dash) is a valid PEP 440 version.","Test the version with Version(version_str) in isolation to see the exact parse failure.","If the project name contains a dash, note that rpartition splits on the LAST dash, so dashes in the name are fine but the version must be dash-free."],"exampleFix":"// before\nparse_sdist_filename('foo-latest.tar.gz')\n// after\nparse_sdist_filename('foo-1.0.tar.gz')","handlingStrategy":"try-catch","validationCode":"from packaging.version import Version, InvalidVersion\n\ndef safe_parse_sdist(filename: str):\n    stem = filename[:-7] if filename.endswith(\".tar.gz\") else filename[:-4]\n    _, _, version_part = stem.rpartition(\"-\")\n    try:\n        Version(version_part)\n    except InvalidVersion:\n        raise ValueError(f\"Invalid version {version_part!r} in sdist {filename!r}\")\n    return parse_sdist_filename(filename)","typeGuard":"from packaging.version import Version\n\ndef has_valid_sdist_version(filename: str) -> bool:\n    if not isinstance(filename, str):\n        return False\n    if filename.endswith(\".tar.gz\"):\n        stem = filename[:-7]\n    elif filename.endswith(\".zip\"):\n        stem = filename[:-4]\n    else:\n        return False\n    _, sep, version_part = stem.rpartition(\"-\")\n    if not sep:\n        return False\n    try:\n        Version(version_part)\n        return True\n    except Exception:\n        return False","tryCatchPattern":"from packaging.utils import InvalidSdistFilename\n\ntry:\n    name, ver = parse_sdist_filename(filename)\nexcept InvalidSdistFilename as e:\n    if \"invalid version\" in str(e):\n        logger.error(\"Sdist version is not PEP 440 compliant: %s\", filename)\n    raise","preventionTips":["Test the version segment with Version() in isolation first","Note that rpartition splits on the LAST dash, so the version must be dash-free","Ensure version strings are PEP 440 compliant before naming the sdist"],"tags":["sdist","filename","version","packaging","pep440"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}