pandas-dev/pandas · error · SyntaxError
The '@' prefix is not allowed in top-level eval…
Error message
The '@' prefix is not allowed in top-level eval calls. please refer to your variables by name without the '@' prefix.
What it means
Raised by _check_for_locals() when the '@' prefix appears in an expression at the top level of the eval stack (level==0) or when using the non-pandas parser. The '@' prefix references local/python-space variables and is only supported inside DataFrame.eval / DataFrame.query (which call eval at a non-zero stack level with the pandas parser). At the top-level pd.eval, there is no meaningful local scope to bind, so it is rejected as a SyntaxError.
Solutions
- Use DataFrame.eval or DataFrame.query instead of pd.eval when you need '@' variable references: df.eval('@x + col').
- If you must use pd.eval, reference variables by name without '@' and pass them via local_dict: pd.eval('x + 1', local_dict={'x': val}).
- Switch to the pandas parser if you were on parser='python' and need '@' inside a non-top-level call.
Example fix
// before
x = 5
pd.eval('@x + 1')
// after (option A)
df.eval('@x + col')
// after (option B)
pd.eval('x + 1', local_dict={'x': x}) Defensive patterns
Strategy: validation
Validate before calling
def safe_eval(expr, **kw):
if '@' in expr:
# use DataFrame.eval with the frame in scope, or pass local_dict
raise ValueError('Use df.eval for @-prefixed variables')
return pd.eval(expr, **kw) Try / catch
try:
pd.eval(expr)
except SyntaxError as e:
if '@' in str(e):
# switch to DataFrame.eval
... Prevention
- Reserve '@' references for DataFrame.eval/df.query, never pd.eval.
- Document clearly which eval flavor supports '@'.
- Use local_dict for top-level variable injection.
When it happens
Trigger: Calling pd.eval('@x + 1') directly instead of df.eval('@x + 1'); calling pd.eval('@x + 1', parser='python') which triggers the 'only supported by the pandas parser' message variant.
Common situations: Confusing top-level pd.eval with DataFrame.eval — users want to reference a Python variable and reach for pd.eval instead of df.eval; tutorials that show df.eval('@var') being copy-pasted into a pd.eval call.
Related errors
- can only assign a single expression
- Invalid Attribute context
- left hand side of an assignment must be a single name
- left hand side of an assignment must be a single resolvable…
- only a single expression is allowed
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/3ae9cc93364f6012.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/eval.py:175
return s
def _check_for_locals(expr: str, stack_level: int, parser: str) -> None:
at_top_of_stack = stack_level == 0
not_pandas_parser = parser != "pandas"
if not_pandas_parser:
msg = "The '@' prefix is only supported by the pandas parser"
elif at_top_of_stack:
msg = (
"The '@' prefix is not allowed in top-level eval calls.\n"
"please refer to your variables by name without the '@' prefix."
)
if at_top_of_stack or not_pandas_parser:
for toknum, tokval in tokenize_string(expr):
if toknum == tokenize.OP and tokval == "@":
raise SyntaxError(msg)
@set_module("pandas")
def eval(
expr: str | BinOp, # we leave BinOp out of the docstr bc it isn't for users
parser: str = "pandas",
engine: str | None = None,
local_dict=None,
global_dict=None,
resolvers=(),
level: int = 0,
target=None,
inplace: bool = False,
) -> Any:
"""
Evaluate a Python expression as a string using various backends.
.. warning::View on GitHub (pinned to 3b7651241d)