pypa/pip · error · InstallationError

Invalid requirement: {req_string!r}: {exc}

Error message

Invalid requirement: {req_string!r}: {exc}

What it means

Raised by install_req_from_req_string() when a raw requirement string fails PEP 508 parsing via get_requirement (constructors.py:456). This is the simplest of the parse paths — there is no path/URL/marker pre-processing, so any syntactically invalid requirement specifier triggers it. Used internally for requirements constructed from already-separated strings.

Source

Thrown at src/pip/_internal/req/constructors.py:457

        isolated=isolated,
        hash_options=hash_options,
        config_settings=config_settings,
        constraint=constraint,
        extras=parts.extras,
        user_supplied=user_supplied,
    )


def install_req_from_req_string(
    req_string: str,
    comes_from: InstallRequirement | None = None,
    isolated: bool = False,
    user_supplied: bool = False,
) -> InstallRequirement:
    try:
        req = get_requirement(req_string)
    except InvalidRequirement as exc:
        raise InstallationError(f"Invalid requirement: {req_string!r}: {exc}")

    domains_not_allowed = [
        PyPI.file_storage_domain,
        TestPyPI.file_storage_domain,
    ]
    if (
        req.url
        and comes_from
        and comes_from.link
        and comes_from.link.netloc in domains_not_allowed
    ):
        # Explicitly disallow pypi packages that depend on external urls
        raise InstallationError(
            "Packages installed from PyPI cannot depend on packages "
            "which are not also hosted on PyPI.\n"
            f"{comes_from.name} depends on {req} "
        )

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Sanitize/validate the requirement string with packaging.requirements.Requirement before passing it in.
  2. Correct the operator/name/extras syntax to conform to PEP 508.
  3. If the string originates from a third-party source, report the malformed metadata upstream.

Example fix

# before
install_req_from_req_string("package =1.0")
# after
install_req_from_req_string("package==1.0")
Defensive patterns

Strategy: validation

Validate before calling

from packaging.requirements import Requirement, InvalidRequirement

def safe_req_string(s: str) -> Requirement:
    try:
        return Requirement(s)
    except InvalidRequirement as e:
        raise ValueError(f"Invalid requirement string {s!r}: {e}") from e

Type guard

from packaging.requirements import Requirement, InvalidRequirement

def is_valid_req_string(s: str) -> bool:
    try:
        Requirement(s)
        return True
    except InvalidRequirement:
        return False

Try / catch

null

Prevention

When it happens

Trigger: Programmatic callers passing a malformed req_string to install_req_from_req_string. Strings with bad operators, unparseable names, or invalid extras syntax like `package[ ]`.

Common situations: Internal pip code paths constructing requirements from dependency metadata. Third-party tools calling install_req_from_req_string with unvalidated user input. Malformed metadata in a wheel or sdist.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/15d656510d98293f.json. Report an issue: GitHub.