pypa/pip · error · InvalidSdistFilename
Invalid sdist filename (invalid version): {filename!r}
Error message
Invalid sdist filename (invalid version): {filename!r} What it means
Raised by `parse_sdist_filename` when the version segment (everything after the last dash in the stem) cannot be parsed as a PEP 440 version via `Version(version_part)`. The underlying `InvalidVersion` is caught and re-raised as `InvalidSdistFilename` with the cause chained (`from e`). Since PEP 440 versions contain no dashes, splitting on the last dash cleanly isolates the version string.
Source
Thrown at src/pip/_vendor/packaging/utils.py:292
file_stem = filename[: -len(".zip")]
else:
raise InvalidSdistFilename(
f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
f" {filename!r}"
)
# We are requiring a PEP 440 version, which cannot contain dashes,
# so we split on the last dash.
name_part, sep, version_part = file_stem.rpartition("-")
if not sep:
raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
name = canonicalize_name(name_part)
try:
version = Version(version_part)
except InvalidVersion as e:
raise InvalidSdistFilename(
f"Invalid sdist filename (invalid version): {filename!r}"
) from e
return (name, version)
View on GitHub (pinned to d7d0d0a394)
Solutions
- Normalize the project version to PEP 440 (drop leading `v`, use setuptools-scm's default normalization).
- Validate the version in isolation with `Version(v)` to see the exact reason, then fix.
- Rename the sdist to embed a valid version segment.
- Rebuild the sdist with a compliant backend.
Example fix
// before
parse_sdist_filename('foo-v1.0.tar.gz') # 'v1.0' invalid -> raises
// after
parse_sdist_filename('foo-1.0.tar.gz') Defensive patterns
Strategy: try-catch
Validate before calling
from pip._vendor.packaging.version import Version, InvalidVersion
def has_valid_sdist_version(filename: str) -> bool:
if filename.endswith('.tar.gz'):
stem = filename[:-7]
elif filename.endswith('.zip'):
stem = filename[:-4]
else:
return False
name_part, sep, version_part = stem.rpartition('-')
if not sep:
return False
try:
Version(version_part)
return True
except InvalidVersion:
return False Try / catch
from pip._vendor.packaging.utils import parse_sdist_filename, InvalidSdistFilename
try:
name, ver = parse_sdist_filename(filename)
except InvalidSdistFilename as e:
if 'invalid version' in str(e):
# normalize the project version to PEP 440, then rebuild/rename
...
raise Prevention
- Keep project versions PEP 440-compliant.
- Normalize VCS-derived versions with setuptools-scm before building sdists.
- Pre-validate the version segment in isolation with `Version()` for a precise error.
When it happens
Trigger: A version segment like `v1.0`, `1.0.beta`, `20240305`, or any non-PEP-440 string after the last dash; sdist built from a project with a git-describe or date-based version that wasn't normalized.
Common situations: Projects setting `version` from `git describe --tags` (e.g. `v1.0-3-gabc`) without normalization; leading `v` in versions; date-only version schemes that violate PEP 440; renamed sdists.
Related errors
- Invalid wheel filename (invalid version): {filename!r}
- Invalid sdist filename (extension must be '.tar.gz' or '.zip
- Invalid sdist filename: {filename!r}
- epoch must be non-negative integer, got {epoch}
- release must be a non-empty tuple of non-negative integers,
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/f65982e3e6d8cf47.json.
Report an issue: GitHub.