{"id":"b9b482cf29bc2989","repo":"pypa/pip","slug":"invalid-sdist-filename-filename-r","errorCode":null,"errorMessage":"Invalid sdist filename: {filename!r}","messagePattern":"Invalid sdist filename: (.+?)","errorType":"validation","errorClass":"InvalidSdistFilename","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/utils.py","lineNumber":285,"sourceCode":"    True\n\n    .. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name\n    \"\"\"\n    if filename.endswith(\".tar.gz\"):\n        file_stem = filename[: -len(\".tar.gz\")]\n    elif filename.endswith(\".zip\"):\n        file_stem = filename[: -len(\".zip\")]\n    else:\n        raise InvalidSdistFilename(\n            f\"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):\"\n            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\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":267,"sourceCodeEnd":297,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/utils.py#L267-L297","documentation":"Raised by `parse_sdist_filename` when, after stripping the `.tar.gz`/`.zip` extension, `file_stem.rpartition('-')` finds no dash at all (`sep == ''`). A valid sdist filename must contain at least one dash separating the project name from the version (e.g. `foo-1.0`). With no dash there is no name/version boundary to split on.","triggerScenarios":"A filename like `foobar.tar.gz` (no dash), or any single-token stem; the parser cannot tell where the name ends and the version begins.","commonSituations":"A malformed/renamed sdist; a project with no version embedded in the filename; an artifact whose name was collapsed.","solutions":["Rename the file to the standard `name-version.tar.gz` (or `.zip`) form.","Rebuild the sdist with a compliant backend, which always emits `name-version`.","Pre-validate that the stem contains a dash before calling.","If you only have a name and version separately, construct the `Version` directly instead of parsing a filename."],"exampleFix":"// before\nparse_sdist_filename('fooonly.tar.gz')  # no dash -> raises\n\n// after\nparse_sdist_filename('fooonly-1.0.tar.gz')","handlingStrategy":"validation","validationCode":"def has_name_version_dash(filename: str) -> bool:\n    if filename.endswith('.tar.gz'):\n        stem = filename[:-len('.tar.gz')]\n    elif filename.endswith('.zip'):\n        stem = filename[:-len('.zip')]\n    else:\n        return False\n    return '-' in stem","typeGuard":"def is_splitable_sdist(filename: object) -> 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    return '-' in stem","tryCatchPattern":"from pip._vendor.packaging.utils import parse_sdist_filename, InvalidSdistFilename\n\ntry:\n    name, ver = parse_sdist_filename(filename)\nexcept InvalidSdistFilename as e:\n    if 'Invalid sdist filename:' in str(e) and 'extension' not in str(e):\n        # no dash; reconstruct name-version from metadata\n        ...\n    raise","preventionTips":["Ensure sdists are named `name-version.tar.gz` with at least one dash.","Use a compliant backend to build sdists so the filename is always correct.","Pre-check that the stem contains a dash before parsing."],"tags":["python","packaging","utils","sdist","filename"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}