{"record":{"id":"adad58cb58425bec","repo":"pandas-dev/pandas","slug":"node-name-nodes-are-not-implemented","errorCode":null,"errorMessage":"'{node_name}' nodes are not implemented","messagePattern":"'(.+?)' nodes are not implemented","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/expr.py","lineNumber":267,"sourceCode":"    | _unsupported_expr_nodes\n) - _hacked_nodes\n\n# we're adding a different assignment in some cases to be equality comparison\n# and we don't want `stmt` and friends in their so get only the class whose\n# names are capitalized\n_base_supported_nodes = (_all_node_names - _unsupported_nodes) | _hacked_nodes\nintersection = _unsupported_nodes & _base_supported_nodes\n_msg = f\"cannot both support and not support {intersection}\"\nassert not intersection, _msg\n\n\ndef _node_not_implemented(node_name: str) -> Callable[..., None]:\n    \"\"\"\n    Return a function that raises a NotImplementedError with a passed node name.\n    \"\"\"\n\n    def f(self, *args, **kwargs):\n        raise NotImplementedError(f\"'{node_name}' nodes are not implemented\")\n\n    return f\n\n\n# should be bound by BaseExprVisitor but that creates a circular dependency:\n# _T is used in disallow, but disallow is used to define BaseExprVisitor\n# https://github.com/microsoft/pyright/issues/2315\n_T = TypeVar(\"_T\")\n\n\ndef disallow(nodes: set[str]) -> Callable[[type[_T]], type[_T]]:\n    \"\"\"\n    Decorator to disallow certain nodes from parsing. Raises a\n    NotImplementedError instead.\n\n    Returns\n    -------\n    callable","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/computation/expr.py#L249-L285","documentation":"Raised by the auto-generated visit_<NodeName> methods created via the @disallow decorator and _node_not_implemented factory. When the AST visitor encounters a Python syntax node that pandas explicitly does not support in eval/query expressions (e.g., Lambda, IfExp/ternary, GeneratorExp/list comprehension, Set, Dict, Yield, Is/IsNot), the corresponding visit method raises NotImplementedError naming the node. The unsupported set is defined in _unsupported_nodes and _unsupported_expr_nodes (expr.py:224-250).","triggerScenarios":"Calling df.query('col > 0 if col else 0') (IfExp ternary — unsupported); df.eval('(x for x in col)') (GeneratorExp); df.eval('lambda x: x') (Lambda); df.query('a is None') (Is/IsNot — unsupported, use isna() instead); df.eval('{1,2,3}') (Set literal).","commonSituations":"Writing Python-native expressions inside query/eval that use language features pandas does not model; expecting full Python semantics from a restricted expression DSL.","solutions":["Rewrite the expression using supported constructs: replace ternary with np.where outside eval; replace 'is None' with isna(); avoid comprehensions and lambdas inside the string.","Move the unsupported logic out of the eval string into regular Python operating on the result of eval.","Switch to engine='python' only if the node is supported by the python parser — but most unsupported nodes (Lambda, GeneratorExp, Set) are blocked at the parser/visitor level for both engines."],"exampleFix":"// before\ndf.query('col > 0 if col else 0')\n\n// after\nimport numpy as np\ndf['result'] = np.where(df['col'] > 0, df['col'], 0)","handlingStrategy":"validation","validationCode":"import ast\nUNSUPPORTED = {'Lambda','IfExp','GeneratorExp','ListComp','SetComp','DictComp','Set','Dict','Yield','Repr','Is','IsNot'}\ndef check_expr_nodes(expr: str):\n    tree = ast.parse(expr, mode='eval')\n    for node in ast.walk(tree):\n        if type(node).__name__ in UNSUPPORTED:\n            raise NotImplementedError(f'{type(node).__name__} not supported in eval')\ncheck_expr_nodes(expr)\ndf.eval(expr)","typeGuard":null,"tryCatchPattern":"try:\n    df.eval(expr)\nexcept NotImplementedError as e:\n    if 'nodes are not implemented' in str(e):\n        # fall back to regular Python ops on columns\n        ...","preventionTips":["Restrict eval strings to arithmetic, comparison, and boolean ops.","Use np.where, isna(), and regular Python for ternary/null/lambda logic.","Avoid 'is'/'is not' — use isna()/notna() for null checks."],"tags":["pandas","eval","query","ast","not-implemented","unsupported-syntax"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}