pypa/pip · error · ValueError

Unexpected file name derived from URL

Error message

Unexpected file name derived from URL: {name!r}

What it means

Raised as ValueError from as_path_component in link.py:53-63. as_path_component reduces a name to a single safe filesystem component (via os.path.basename) and is meant to reject names that would collapse to empty/./.. before writing a file. If after basename reduction the result is empty (e.g. the URL-derived name is empty, '.', '..', or only a separator), it raises ValueError because writing under such a name would be unsafe (it could escape or overwrite the target directory).

Solutions

  1. Ensure the source URL resolves to a concrete file name with a real basename component.
  2. Validate/sanitize the link's URL-derived name before passing to as_path_component.
  3. Report the offending URL to pip maintainers if it is a legitimate index link.

Example fix

// before: URL yields empty basename
name = ''  # derived from a directory-only URL
component = as_path_component(name)
// after: guard against empty names
if not name or os.path.basename(name) in ('', '.', '..'):
    raise ValueError(f'No usable file name in URL')
component = as_path_component(name)
Defensive patterns

Strategy: validation

Validate before calling

// Before calling as_path_component, ensure the URL yields a real basename:
import os
base = os.path.basename(name)
if base in ('', os.curdir, os.pardir):
    raise ValueError(f'URL produces no usable file name: {name!r}')
component = as_path_component(name)

Try / catch

try:
    component = as_path_component(name)
except ValueError:
    # synthesize a safe name or reject the link
    ...

Prevention

When it happens

Trigger: Calling as_path_component(name) where name, after os.path.basename, is '', '.', or '..' — e.g. a Link whose URL yields an empty/relative file name component when pip derives a cache/download path.

Common situations: A malformed Link URL that produces no usable file name (trailing slash, directory-only URL, drive-letter-only on Windows); a crafted/edge-case URL that basename reduces to '.' or '..'; a bug in URL-to-filename derivation.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/models/link.py:61

    ``os.path.basename`` drops any directory part, drive letter, or separator;
    a ``.``, ``..``, or empty result is not a component and becomes ``""``.
    """
    name = os.path.basename(name)
    if name in ("", os.curdir, os.pardir):
        return PathComponent("")

    return PathComponent(name)


def as_path_component(name: str) -> PathComponent:
    """Like ``_to_path_component`` but reject the empty result.

    Use where a file is about to be written, so a missing name is an error
    rather than a silent fallback to the directory itself.
    """
    component = _to_path_component(name)
    if not component:
        raise ValueError(f"Unexpected file name derived from URL: {name!r}")

    return component


def join_within_directory(directory: str, component: PathComponent) -> str:
    """Join a single path ``component`` onto ``directory``.

    ``component`` is a :data:`PathComponent`, so by type it has no separator and
    is not a ``.`` or ``..`` reference; the result can never escape ``directory``.
    Requiring ``PathComponent`` rather than ``str`` lets the type checker enforce
    at the call site that the name was reduced to a safe component beforehand.
    """
    return os.path.join(directory, component)


# Order matters, earlier hashes have a precedence over later hashes for what
# we will pick to use.
_SUPPORTED_HASHES = ("sha512", "sha384", "sha256", "sha224", "sha1", "md5")

View on GitHub (pinned to f399c37189)