pandas-dev/pandas · error · NotImplementedError

' ' nodes are not implemented

Error message

'{node_name}' nodes are not implemented

What it means

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).

Solutions

  1. 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.
  2. Move the unsupported logic out of the eval string into regular Python operating on the result of eval.
  3. 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.

Example fix

// before
df.query('col > 0 if col else 0')

// after
import numpy as np
df['result'] = np.where(df['col'] > 0, df['col'], 0)
Defensive patterns

Strategy: validation

Validate before calling

import ast
UNSUPPORTED = {'Lambda','IfExp','GeneratorExp','ListComp','SetComp','DictComp','Set','Dict','Yield','Repr','Is','IsNot'}
def check_expr_nodes(expr: str):
    tree = ast.parse(expr, mode='eval')
    for node in ast.walk(tree):
        if type(node).__name__ in UNSUPPORTED:
            raise NotImplementedError(f'{type(node).__name__} not supported in eval')
check_expr_nodes(expr)
df.eval(expr)

Try / catch

try:
    df.eval(expr)
except NotImplementedError as e:
    if 'nodes are not implemented' in str(e):
        # fall back to regular Python ops on columns
        ...

Prevention

When it happens

Trigger: 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).

Common situations: Writing Python-native expressions inside query/eval that use language features pandas does not model; expecting full Python semantics from a restricted expression DSL.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/adad58cb58425bec. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/computation/expr.py:267

    | _unsupported_expr_nodes
) - _hacked_nodes

# we're adding a different assignment in some cases to be equality comparison
# and we don't want `stmt` and friends in their so get only the class whose
# names are capitalized
_base_supported_nodes = (_all_node_names - _unsupported_nodes) | _hacked_nodes
intersection = _unsupported_nodes & _base_supported_nodes
_msg = f"cannot both support and not support {intersection}"
assert not intersection, _msg


def _node_not_implemented(node_name: str) -> Callable[..., None]:
    """
    Return a function that raises a NotImplementedError with a passed node name.
    """

    def f(self, *args, **kwargs):
        raise NotImplementedError(f"'{node_name}' nodes are not implemented")

    return f


# should be bound by BaseExprVisitor but that creates a circular dependency:
# _T is used in disallow, but disallow is used to define BaseExprVisitor
# https://github.com/microsoft/pyright/issues/2315
_T = TypeVar("_T")


def disallow(nodes: set[str]) -> Callable[[type[_T]], type[_T]]:
    """
    Decorator to disallow certain nodes from parsing. Raises a
    NotImplementedError instead.

    Returns
    -------
    callable

View on GitHub (pinned to 3b7651241d)