pytest-dev/pytest · error · SyntaxError
unexpected character/s "{value_token.value}"
Error message
unexpected character/s "{value_token.value}" What it means
In `ident(name=value)` the value must be a quoted string, an integer literal, or one of `True`/`False`/`None`. If the value token is an unquoted identifier (or any token that is none of those), this SyntaxError is raised at the value's column. Marker kwarg values are literals, not references to other markers.
Source
Thrown at src/_pytest/mark/expression.py:239
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}"',
(FILE_NAME, 1, value_token.pos + 1, s.input),
)
ret = ast.keyword(keyword_name.value, ast.Constant(value))
return ret
def all_kwargs(s: Scanner) -> list[ast.keyword]:
ret = [single_kwarg(s)]
while s.accept(TokenType.COMMA):
ret.append(single_kwarg(s))
return ret
class ExpressionMatcher(Protocol):
"""A callable which, given an identifier and optional kwargs, should return
whether it matches in an :class:`Expression` evaluation.View on GitHub (pinned to 98b357f69e)
Solutions
- Quote string values: `foo(x="bar")`.
- Use integer literals (`foo(x=5)`, `foo(x=-3)`) or the booleans/None builtins only.
- For floats or symbolic references, encode them as strings and decode in your matcher.
Example fix
# before pytest -m 'config(env=prod)' # after pytest -m 'config(env="prod")'
Defensive patterns
Strategy: validation
Validate before calling
def kwarg_value_ok(v: str) -> bool:
if v in ('True', 'False', 'None'):
return True
digits = v.lstrip('-')
if digits.isdigit():
return True
return len(v) >= 2 and v[0] == v[-1] and v[0] in (chr(39), chr(34)) Prevention
- Always quote string values.
- Encode floats/symbols as quoted strings and decode in the matcher.
When it happens
Trigger: `foo(x=bar)` where `bar` is unquoted, or `foo(x=1.5)` (floats are not allowed), or `foo(x=-)`.
Common situations: Assuming kwarg values can reference other markers/variables; pasting enum names or floats as values.
Related errors
- not a valid python identifier {keyword_name.value}
- unexpected reserved python keyword `{keyword_name.value}`
- {self.inipath}: config option '{name}' expects one of {_ini_
- invalid truth value {val!r}
- {exc_message}: {e.text}: at column {e.offset}: {e.msg}
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/27783714a895dcad.json.
Report an issue: GitHub.