{"record":{"id":"dc296d01e9343e2d","repo":"pypa/pip","slug":"str-e","errorCode":null,"errorMessage":"{str(e)}","messagePattern":"\\{str\\(e\\)\\}","errorType":"validation","errorClass":"InvalidRequirement","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/requirements.py","lineNumber":86,"sourceCode":"        override; it is now included again.\n\n        Equality and hashing normalize requirement names, extras, and\n        equivalent specifiers. The string representation still preserves the\n        parsed name and extras spelling.\n    \"\"\"\n\n    # TODO: Can we test whether something is contained within a requirement?\n    #       If so how do we do that? Do we need to test against the _name_ of\n    #       the thing as well as the version? What about the markers?\n    # TODO: Can we normalize the name and extra name?\n\n    __slots__ = (\"extras\", \"marker\", \"name\", \"specifier\", \"url\")\n\n    def __init__(self, requirement_string: str) -> None:\n        try:\n            parsed = _parse_requirement(requirement_string)\n        except ParserSyntaxError as e:\n            raise InvalidRequirement(str(e)) from e\n\n        self.name: str = parsed.name\n        self.url: str | None = parsed.url or None\n        self.extras: set[str] = set(parsed.extras)\n        try:\n            self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)\n        except InvalidSpecifier as e:\n            raise InvalidRequirement(str(e)) from e\n        self.marker: Marker | None = None\n        if parsed.marker is not None:\n            self.marker = Marker.__new__(Marker)\n            self.marker._markers = _normalize_extra_values(parsed.marker)\n\n    def _iter_parts(self, name: str) -> Iterator[str]:\n        yield name\n\n        if self.extras:\n            formatted_extras = \",\".join(sorted(self.extras))","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/requirements.py#L68-L104","documentation":"InvalidRequirement raised by Requirement.__init__ when the PEP 508 requirement string fails tokenizing/parsing (a ParserSyntaxError from the parser). This covers malformed name, extras, URL, or marker syntax — anything the grammar rejects before specifier validation even begins.","triggerScenarios":"Calling Requirement('foo >=1.0') is fine, but Requirement('foo bar') (illegal token), Requirement('[extra]foo') (extras before name), Requirement('foo @') (incomplete URL), or Requirement('foo;') (empty marker) raise from _parse_requirement.","commonSituations":"User-supplied requirements.txt lines; a dependency string built by string concatenation that drops a needed operator; copy-paste of a PEP 508 string with a stray character; a marker missing its value.","solutions":["Read the ParserSyntaxError detail embedded in the InvalidRequirement message to find the offending position/token.","Reformat the string to valid PEP 508: 'name[extra] specifier ; marker', e.g. 'requests[security]>=2.31,<3; python_version>=\"3.8\"'.","If the string comes from a file, trim whitespace/comments and validate line-by-line.","For programmatic construction, build name, specifier, and marker separately and join with the documented operators."],"exampleFix":"# before\nRequirement('requests security>=2.31')  # InvalidRequirement\n\n# after\nRequirement('requests[security]>=2.31')","handlingStrategy":"try-catch","validationCode":"from packaging.requirements import Requirement, InvalidRequirement\n\ndef parse_requirement_safe(s: str):\n    try:\n        return Requirement(s), None\n    except InvalidRequirement as e:\n        return None, str(e)\n\nreq, err = parse_requirement_safe(line)\nif err:\n    # report the offending line and skip; do not crash the whole import\n    ...","typeGuard":"null","tryCatchPattern":"from packaging.requirements import InvalidRequirement\nfor line in lines:\n    try:\n        req = Requirement(line)\n    except InvalidRequirement as e:\n        log.warning(\"skipping invalid requirement %r: %s\", line, e)\n        continue\n    requirements.append(req)","preventionTips":["Treat user-supplied requirement strings as untrusted input; validate each line.","Build requirements programmatically from name/specifier/marker components rather than f-strings.","Strip comments and whitespace before parsing requirements.txt lines."],"tags":["packaging","requirement","pep508","parsing"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}