{"record":{"id":"3ae9cc93364f6012","repo":"pandas-dev/pandas","slug":"the-prefix-is-not-allowed-in-top-level-eval-ca","errorCode":null,"errorMessage":"The '@' prefix is not allowed in top-level eval calls.\nplease refer to your variables by name without the '@' prefix.","messagePattern":"The '@' prefix is not allowed in top-level eval calls\\.\nplease refer to your variables by name without the '@' prefix\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/eval.py","lineNumber":175,"sourceCode":"    return s\n\n\ndef _check_for_locals(expr: str, stack_level: int, parser: str) -> None:\n    at_top_of_stack = stack_level == 0\n    not_pandas_parser = parser != \"pandas\"\n\n    if not_pandas_parser:\n        msg = \"The '@' prefix is only supported by the pandas parser\"\n    elif at_top_of_stack:\n        msg = (\n            \"The '@' prefix is not allowed in top-level eval calls.\\n\"\n            \"please refer to your variables by name without the '@' prefix.\"\n        )\n\n    if at_top_of_stack or not_pandas_parser:\n        for toknum, tokval in tokenize_string(expr):\n            if toknum == tokenize.OP and tokval == \"@\":\n                raise SyntaxError(msg)\n\n\n@set_module(\"pandas\")\ndef eval(\n    expr: str | BinOp,  # we leave BinOp out of the docstr bc it isn't for users\n    parser: str = \"pandas\",\n    engine: str | None = None,\n    local_dict=None,\n    global_dict=None,\n    resolvers=(),\n    level: int = 0,\n    target=None,\n    inplace: bool = False,\n) -> Any:\n    \"\"\"\n    Evaluate a Python expression as a string using various backends.\n\n    .. warning::","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/eval.py#L157-L193","documentation":"The '@' prefix resolves caller locals by walking up the call stack inside ensure_scope. A bare top-level pd.eval call (level=0, at_top_of_stack) has no enclosing DataFrame method frame to harvest locals from, so pandas refuses rather than silently resolving to the wrong scope. The fix the message points to is to reference variables by name (relying on local_dict/globals) or to use a DataFrame.eval/query call whose frame provides the scope.","triggerScenarios":"pd.eval('@x + 1') called directly at module level, in a script, or in any frame where level resolves to 0 (the default level kwarg). Any direct pd.eval invocation that embeds a local-variable reference with '@'.","commonSituations":"Promoting a df.query('@threshold > col') snippet to a standalone pd.eval call without a DataFrame context. Notebooks where users expect @ to work like IPython magic. Calling pd.eval inside a helper but forgetting to forward level.","solutions":["Use DataFrame.eval or DataFrame.query instead of pd.eval, so the calling frame supplies the locals scope.","Drop the '@' and pass the variable through local_dict, e.g. pd.eval('x + 1', local_dict={'x': x}).","If you must call pd.eval from a wrapper, forward level appropriately so stack walking reaches your caller's frame."],"exampleFix":"// before\nresult = pd.eval('@x + 1')\n// after\nresult = pd.eval('x + 1', local_dict={'x': x})","handlingStrategy":"validation","validationCode":"def check_top_level_at(expr: str, level: int) -> None:\n    import tokenize\n    from pandas.core.computation.parsing import tokenize_string\n    if level == 0:\n        for toknum, tokval in tokenize_string(expr):\n            if toknum == tokenize.OP and tokval == '@':\n                raise ValueError(\n                    \"'@' is disallowed in top-level pd.eval; \"\n                    \"use df.query/df.eval or pass local_dict\"\n                )\n\ncheck_top_level_at(expr, level=0)","typeGuard":"def is_safe_for_top_eval(expr: str) -> bool:\n    return '@' not in expr","tryCatchPattern":"try:\n    pd.eval(expr)\nexcept SyntaxError as e:\n    if '@' in expr:\n        # resolve locals explicitly and retry\n        pd.eval(expr.replace('@', ''), local_dict=locals())\n    else:\n        raise","preventionTips":["Never embed '@' in expressions passed to pd.eval at module/script level.","Forward explicit local_dict instead of relying on '@' scope capture.","Reserve '@' usage for df.query and df.eval where the calling frame is meaningful."],"tags":["pandas","eval","scope","stack-frame"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}