{"record":{"id":"e0635fc69f0e31b4","repo":"pypa/pip","slug":"invalid-quoted-string","errorCode":null,"errorMessage":"Invalid quoted string","messagePattern":"Invalid quoted string","errorType":"validation","errorClass":"ParserSyntaxError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/_parser.py","lineNumber":378,"sourceCode":"    marker_op = _parse_marker_op(tokenizer)\n    tokenizer.consume(\"WS\")\n    marker_var_right = _parse_marker_var(tokenizer)\n    tokenizer.consume(\"WS\")\n    return (marker_var_left, marker_op, marker_var_right)\n\n\ndef _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:  # noqa: RET503\n    \"\"\"\n    marker_var = VARIABLE | QUOTED_STRING\n    \"\"\"\n    if tokenizer.check(\"VARIABLE\"):\n        return process_env_var(tokenizer.read().text.replace(\".\", \"_\"))\n    elif tokenizer.check(\"QUOTED_STRING\"):\n        token = tokenizer.read()\n        try:\n            return process_python_str(token.text)\n        except (SyntaxError, ValueError) as exc:\n            raise ParserSyntaxError(\n                \"Invalid quoted string\",\n                source=tokenizer.source,\n                span=(token.position, token.position + len(token.text)),\n            ) from exc\n    else:\n        tokenizer.raise_syntax_error(\n            message=\"Expected a marker variable or quoted string\"\n        )\n\n\ndef process_env_var(env_var: str) -> Variable:\n    if env_var in (\"platform_python_implementation\", \"python_implementation\"):\n        return Variable(\"platform_python_implementation\")\n    else:\n        return Variable(env_var)\n\n\ndef process_python_str(python_str: str) -> Value:","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/_parser.py#L360-L396","documentation":"When parsing a PEP 508 environment marker, _parse_marker_var encounters a QUOTED_STRING token and processes it via process_python_str, which calls ast.literal_eval. If the string cannot be safely evaluated (malformed quotes, invalid escape sequences), SyntaxError or ValueError is caught and ParserSyntaxError('Invalid quoted string') is raised with a span pointing at the offending token.","triggerScenarios":"Calling parse_marker(), parse_requirement(), or constructing Requirement/Marker objects with a specifier containing a malformed quoted string in an environment marker, e.g. python_version >= \"3.8 (missing closing quote).","commonSituations":"Typos in requirements.txt or pyproject.toml markers. Programmatically building requirement strings with unescaped or mismatched quotes. Copy-paste errors in dependency specifiers.","solutions":["Fix the quoting in the marker expression so every quoted string has matching opening/closing quotes of the same type","Use consistent quote style (single quotes) throughout marker expressions","Validate requirement strings with Requirement() early during config loading to surface errors immediately"],"exampleFix":"# before\nfrom packaging.requirements import Requirement\nreq = Requirement('django>=4.0 ; python_version >= \"3.8')  # unclosed quote\n\n# after\nreq = Requirement(\"django>=4.0 ; python_version >= '3.8'\")  # properly quoted","handlingStrategy":"try-catch","validationCode":"def validate_marker_quoting(marker_str: str) -> bool:\n    for quote_char in ('\"', \"'\"):\n        if marker_str.count(quote_char) % 2 != 0:\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"from packaging.requirements import Requirement, InvalidRequirement\nfrom packaging._tokenizer import ParserSyntaxError\n\ntry:\n    req = Requirement(req_string)\nexcept (InvalidRequirement, ParserSyntaxError) as e:\n    print(f\"Invalid requirement syntax: {e}\")","preventionTips":["Validate requirement strings at config load time","Use consistent single-quote style in markers","Lint requirements files for syntax errors","Test programmatic requirement string construction with unit tests"],"tags":["packaging","markers","pep508","parsing","vendored"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}