pytest-dev/pytest · error · SyntaxError
not a valid python identifier {keyword_name.value}
Error message
not a valid python identifier {keyword_name.value} What it means
Inside `ident(name=value)` kwargs, the `name` part must be a valid Python identifier. After lexing it as an IDENT token the parser checks `str.isidentifier()`; if it fails (e.g. starts with a digit, contains `-`), this SyntaxError is raised at the name's column.
Source
Thrown at src/_pytest/mark/expression.py:217
if ident:
name = ast.Name(IDENT_PREFIX + ident.value, ast.Load())
if s.accept(TokenType.LPAREN):
ret = ast.Call(func=name, args=[], keywords=all_kwargs(s))
s.accept(TokenType.RPAREN, reject=True)
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)View on GitHub (pinned to 98b357f69e)
Solutions
- Rename the kwarg to a valid Python identifier (letters/digits/underscore, not starting with a digit).
- Register the marker with a proper identifier name and map the external key inside your matcher.
Example fix
# before pytest -m 'env(target-os=linux)' # after pytest -m 'env(target_os="linux")'
Defensive patterns
Strategy: validation
Validate before calling
def kwarg_name_ok(name: str) -> bool:
return name.isidentifier() Type guard
def is_valid_kwarg_name(name: object) -> bool:
return isinstance(name, str) and name.isidentifier() Prevention
- Use snake_case identifier names for kwargs.
- Avoid digits at the start and `-`/special chars in kwarg names.
When it happens
Trigger: Writing `foo(1st=...)`, `foo(my-name=...)`, or any kwarg name with non-identifier characters in a `-m` expression.
Common situations: Using kebab-case or numeric-prefixed kwarg names; pasting config keys verbatim into marker expressions.
Related errors
- unexpected reserved python keyword `{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/0fc7ef7b8eea2769.json.
Report an issue: GitHub.