pytest-dev/pytest · error · SyntaxError
unexpected character "{input[pos]}"
Error message
unexpected character "{input[pos]}" What it means
Raised by the scanner when the current character is not whitespace, not one of `()` `=` `,` quotes, and does not begin a valid identifier token (the regex `(:?\w|:|\+|-|\.|\[|\]|\\|/)+`). It reports the offending character and its 1-based column.
Source
Thrown at src/_pytest/mark/expression.py:126
(FILE_NAME, 1, pos + backslash_pos + 1, input),
)
yield Token(TokenType.STRING, value, pos)
pos += len(value)
else:
match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\|/)+", input[pos:])
if match:
value = match.group(0)
if value == "or":
yield Token(TokenType.OR, value, pos)
elif value == "and":
yield Token(TokenType.AND, value, pos)
elif value == "not":
yield Token(TokenType.NOT, value, pos)
else:
yield Token(TokenType.IDENT, value, pos)
pos += len(value)
else:
raise SyntaxError(
f'unexpected character "{input[pos]}"',
(FILE_NAME, 1, pos + 1, input),
)
yield Token(TokenType.EOF, "", pos)
@overload
def accept(self, type: TokenType, *, reject: Literal[True]) -> Token: ...
@overload
def accept(
self, type: TokenType, *, reject: Literal[False] = False
) -> Token | None: ...
def accept(self, type: TokenType, *, reject: bool = False) -> Token | None:
if self.current.type is type:
token = self.current
if token.type is not TokenType.EOF:
self.current = next(self.tokens)View on GitHub (pinned to 98b357f69e)
Solutions
- Quote the expression so the shell does not expand `*`/`?`/`!`.
- Use only the supported operators `and`, `or`, `not`, parentheses, and identifiers.
- For substring matching on test names remember `-k` already does substring match on identifiers — no wildcards needed.
Example fix
# before pytest -k 'test_* && not slow' # after pytest -k 'test_ and not slow'
Defensive patterns
Strategy: validation
Validate before calling
from _pytest.mark.expression import Expression
def only_allowed_chars(expr: str) -> bool:
try:
Expression.compile(expr)
except SyntaxError:
return False
return True Prevention
- Quote the expression so the shell cannot inject `*`, `?`, `!`.
- Use only `and`/`or`/`not`/parens/identifiers.
When it happens
Trigger: Including characters like `@`, `*`, `&`, `!`, `?`, `;` in a `-k`/`-m` expression; using Python operators (`and&&`, `||`) that don't exist in the grammar.
Common situations: Confusing pytest's mini-grammar with Python boolean operators; pasting a regex or glob into `-k`; stray shell glob expansions (`*`) reaching pytest.
Related errors
- closing quote "{quote_char}" is missing
- escaping with "\" not supported in marker expression
- {exc_message}: {e.text}: at column {e.offset}: {e.msg}
- expected {}; got {}
- not a valid python identifier {keyword_name.value}
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/de9a487940d93909.json.
Report an issue: GitHub.