pypa/pip · error · PylockValidationError

Cannot determine sdist filename

Error message

Cannot determine sdist filename

What it means

Raised by the PackageSdist.filename property in pylock.py:480-483 when none of 'name', the basename of 'path', or the basename of 'url' yields a filename. The property is used inside Package._from_dict (pylock.py:635) to run parse_sdist_filename, and is also part of the public API.

Solutions

  1. Set name = "pkg-1.0.tar.gz" explicitly, or
  2. Fix path/url so its last segment is the sdist filename (remove trailing slash).

Example fix

# before
[[packages.sdist]]
url = "https://example.com/"
hashes = { sha256 = "..." }
# after
[[packages.sdist]]
url = "https://example.com/pkg-1.0.tar.gz"
hashes = { sha256 = "..." }
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse, unquote

def sdist_filename_resolvable(name, path, url) -> bool:
    if name:
        return True
    if path and path.rsplit("/", 1)[-1]:
        return True
    if url:
        last = unquote(urlparse(url).path.rsplit("/", 1)[-1])
        return bool(last)
    return False

Try / catch

from packaging.pylock import Pylock, PylockValidationError

try:
    Pylock.from_dict(d)
except PylockValidationError as e:
    ...

Prevention

When it happens

Trigger: An sdist entry with no name, no path, and a url whose final path segment is empty (e.g. url = "https://example.com/" or a directory URL ending in '/').

Common situations: URL with a trailing slash and no filename component; forgetting to set 'name' when path/url lack a usable basename.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/1c050aca6ea4a852. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/packaging/pylock.py:482

            name=_get(d, str, "name"),
            upload_time=_get(d, datetime, "upload-time"),
            url=_get(d, str, "url"),
            path=_get(d, str, "path"),
            size=_get(d, int, "size"),
            hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"),  # type: ignore[type-abstract]
        )
        _validate_path_url(package_sdist.path, package_sdist.url)
        return package_sdist

    @property
    def filename(self) -> str:
        """Get the filename of the sdist.

        .. versionadded:: 26.1
        """
        filename = self.name or _path_name(self.path) or _url_name(self.url)
        if not filename:
            raise PylockValidationError("Cannot determine sdist filename")
        return filename


@dataclass(frozen=True, init=False)
class PackageWheel:
    name: str | None = None
    upload_time: datetime | None = None
    url: str | None = None
    path: str | None = None
    size: int | None = None
    hashes: Mapping[str, str]  # type: ignore[misc]

    def __init__(
        self,
        *,
        name: str | None = None,
        upload_time: datetime | None = None,
        url: str | None = None,

View on GitHub (pinned to f399c37189)