{"id":"835b8ee9c30281c1","repo":"pypa/pip","slug":"invalid-requirement-req-as-string-r-exc","errorCode":null,"errorMessage":"Invalid requirement: {req_as_string!r}: {exc}","messagePattern":"Invalid requirement: (.+?): (.+?)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/req/constructors.py","lineNumber":405,"sourceCode":"        return f\"{text} (from {line_source})\"\n\n    def _parse_req_string(req_as_string: str) -> Requirement:\n        try:\n            return get_requirement(req_as_string)\n        except InvalidRequirement as exc:\n            if os.path.sep in req_as_string:\n                add_msg = \"It looks like a path.\"\n                add_msg += deduce_helpful_msg(req_as_string)\n            elif \"=\" in req_as_string and not any(\n                op in req_as_string for op in operators\n            ):\n                add_msg = \"= is not a valid operator. Did you mean == ?\"\n            else:\n                add_msg = \"\"\n            msg = with_source(f\"Invalid requirement: {req_as_string!r}: {exc}\")\n            if add_msg:\n                msg += f\"\\nHint: {add_msg}\"\n            raise InstallationError(msg)\n\n    if req_as_string is not None:\n        req: Requirement | None = _parse_req_string(req_as_string)\n    else:\n        req = None\n\n    return RequirementParts(req, link, markers, extras)\n\n\ndef install_req_from_line(\n    name: str,\n    comes_from: str | InstallRequirement | None = None,\n    *,\n    isolated: bool = False,\n    hash_options: dict[str, list[str]] | None = None,\n    constraint: bool = False,\n    line_source: str | None = None,\n    user_supplied: bool = False,","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/req/constructors.py#L387-L423","documentation":"Raised by the inner _parse_req_string() in parse_req_from_line() when the requirement string itself (after path/URL/marker handling) cannot be parsed by get_requirement as a valid PEP 508 requirement. The error at constructors.py:405 includes a smart hint: it detects path-like strings, single-`=` mistakes, etc.","triggerScenarios":"A requirements line with bad syntax: `package =1.0` (single equals), an unparseable name, a version specifier with stray characters, or a path-like token that is neither a valid file nor a valid requirement. The hint logic at constructors.py:393-404 appends advice based on heuristics.","commonSituations":"Using `=` instead of `==`. Forgetting the package name and writing just a version. Stray whitespace or non-ASCII characters. A requirements file accidentally passed without -r.","solutions":["Follow the Hint in the error message: if it suggests `==`, replace single `=` with `==`.","If the hint says the argument looks like a requirements file, re-run with `-r <file>`.","Validate the line standalone: `python -c \"from packaging.requirements import Requirement; Requirement('YOUR_LINE')\"`.","Strip invisible characters and normalize quotes if copy-pasted from a rich-text source."],"exampleFix":"# before\npackage =1.0\n# after\npackage==1.0","handlingStrategy":"validation","validationCode":"from packaging.requirements import Requirement, InvalidRequirement\n\ndef validate_req_line(line: str) -> Requirement:\n    # strip markers/path handling is pip's job; here we sanity-check the core specifier\n    core = line.split(\";\", 1)[0].strip()\n    try:\n        return Requirement(core)\n    except InvalidRequirement as e:\n        raise ValueError(f\"Invalid requirement line {line!r}: {e}\") from e","typeGuard":"from packaging.requirements import Requirement, InvalidRequirement\n\ndef is_valid_req_line(line: str) -> bool:\n    try:\n        Requirement(line.split(\";\", 1)[0].strip())\n        return True\n    except InvalidRequirement:\n        return False","tryCatchPattern":"null","preventionTips":["Use == instead of = for version pinning.","If pip hints the arg looks like a requirements file, pass it with -r.","Lint requirements files in CI by parsing every line with packaging."],"tags":["requirements","pep508","validation","packaging"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}