pytest-dev/pytest · error · SyntaxError
unexpected reserved python keyword `{keyword_name.value}`
Error message
unexpected reserved python keyword `{keyword_name.value}` What it means
The kwarg name in `ident(name=value)` lexes as a valid identifier but collides with a reserved Python keyword (`class`, `def`, `return`, `lambda`, ...). Because the compiled expression is turned into Python AST, reserved words cannot be used as kwarg names; this SyntaxError is raised at the name's column.
Source
Thrown at src/_pytest/mark/expression.py:222
else:
ret = name
return ret
s.reject((TokenType.NOT, TokenType.LPAREN, TokenType.IDENT))
BUILTIN_MATCHERS = {"True": True, "False": False, "None": None}
def single_kwarg(s: Scanner) -> ast.keyword:
keyword_name = s.accept(TokenType.IDENT, reject=True)
if not keyword_name.value.isidentifier():
raise SyntaxError(
f"not a valid python identifier {keyword_name.value}",
(FILE_NAME, 1, keyword_name.pos + 1, s.input),
)
if keyword.iskeyword(keyword_name.value):
raise SyntaxError(
f"unexpected reserved python keyword `{keyword_name.value}`",
(FILE_NAME, 1, keyword_name.pos + 1, s.input),
)
s.accept(TokenType.EQUAL, reject=True)
if value_token := s.accept(TokenType.STRING):
value: str | int | bool | None = value_token.value[1:-1] # strip quotes
else:
value_token = s.accept(TokenType.IDENT, reject=True)
if (number := value_token.value).isdigit() or (
number.startswith("-") and number[1:].isdigit()
):
value = int(number)
elif value_token.value in BUILTIN_MATCHERS:
value = BUILTIN_MATCHERS[value_token.value]
else:
raise SyntaxError(
f'unexpected character/s "{value_token.value}"',View on GitHub (pinned to 98b357f69e)
Solutions
- Pick a non-reserved synonym (e.g. `klass`, `returns`).
- When generating expressions programmatically, skip names where `keyword.iskeyword(name)` is True.
Example fix
# before pytest -m 'schema(class=user)' # after pytest -m 'schema(klass="user")'
Defensive patterns
Strategy: validation
Validate before calling
import keyword
def not_reserved(name: str) -> bool:
return not keyword.iskeyword(name) Type guard
import keyword
def is_safe_kwarg_name(name: object) -> bool:
return isinstance(name, str) and name.isidentifier() and not keyword.iskeyword(name) Prevention
- Filter generated kwarg names with `keyword.iskeyword`.
- Prefer domain prefixes (`klass`) for keyword-like concepts.
When it happens
Trigger: `foo(class=...)`, `foo(return=...)`, or any kwarg whose name is a Python keyword.
Common situations: Naming kwargs after Python keywords for domain readability; generating marker expressions programmatically without filtering keywords.
Related errors
- not a valid python identifier {keyword_name.value}
- unexpected character/s "{value_token.value}"
- {exc_message}: {e.text}: at column {e.offset}: {e.msg}
- closing quote "{quote_char}" is missing
- escaping with "\" not supported in marker expression
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/ccbc86137abb25a9.json.
Report an issue: GitHub.