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

  1. Quote string values: `foo(x="bar")`.
  2. Use integer literals (`foo(x=5)`, `foo(x=-3)`) or the booleans/None builtins only.
  3. 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

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


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/27783714a895dcad.json. Report an issue: GitHub.