pypa/pip · error · ParserSyntaxError
Expected extra name after comma
Error message
Expected extra name after comma
What it means
Raised as a ParserSyntaxError (surfacing as InvalidRequirement) at line 245 inside _parse_extras_list: after consuming a comma in an extras list (line 242), tokenizer.expect("IDENTIFIER", expected="extra name after comma") fails because no valid identifier follows the comma. The grammar (line 226) requires an identifier after each comma.
Solutions
- Remove the trailing/empty comma: 'pkg[a,b]' instead of 'pkg[a,b,]'.
- When building extras programmatically, filter empties and avoid a trailing comma: '[' + ','.join(filter(None, extras)) + ']'.
- Validate the extras segment parses before using it.
Example fix
// before
Requirement('pkg[dev,test,]')
// after
Requirement('pkg[dev,test]') Defensive patterns
Strategy: validation
Validate before calling
def clean_extras(extras):
return [e for e in (x.strip() for x in extras) if e]
def extras_str(extras):
return '[' + ','.join(clean_extras(extras)) + ']' if clean_extras(extras) else '' Try / catch
from packaging.requirements import Requirement, InvalidRequirement
try:
req = Requirement(raw)
except InvalidRequirement as e:
if 'extra name after comma' in str(e):
# strip trailing/empty commas in the extras bracket
raw = re.sub(r',+', ',', raw)
raise Prevention
- When joining extras programmatically, filter falsy values and never append a trailing comma.
- Treat the extras segment as structured data, not free-form text.
When it happens
Trigger: A requirement with a trailing comma in extras, e.g. 'pkg[a,]', or an empty slot like 'pkg[a,,b]', or a non-identifier token after the comma, e.g. 'pkg[a,2]'. After tokenizer.read() consumes the comma (line 242), the next token is not an IDENTIFIER.
Common situations: Programmatically joining extras with a trailing comma (','.join(extras) + ','); user-edited extras strings with a stray comma; copy-paste leaving a dangling comma.
Related errors
- Expected end of dependency specifier
- Expected URL after @
- Expected end of marker expression
- Expected whitespace after 'not'
- Expected whitespace after URL
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/7339376c9970e3ad.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/_parser.py:245
"""
extras: list[str] = []
if not tokenizer.check("IDENTIFIER"):
return extras
extras.append(tokenizer.read().text)
while True:
tokenizer.consume("WS")
if tokenizer.check("IDENTIFIER", peek=True):
tokenizer.raise_syntax_error("Expected comma between extra names")
elif not tokenizer.check("COMMA"):
break
tokenizer.read()
tokenizer.consume("WS")
extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma")
extras.append(extra_token.text)
return extras
def _parse_specifier(tokenizer: Tokenizer) -> str:
"""
specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
| WS? version_many WS?
"""
with tokenizer.enclosing_tokens(
"LEFT_PARENTHESIS",
"RIGHT_PARENTHESIS",
around="version specifier",
):
tokenizer.consume("WS")
parsed_specifiers = _parse_version_many(tokenizer)
tokenizer.consume("WS")View on GitHub (pinned to f399c37189)