pandas-dev/pandas · error · TypeError

Only named functions are supported

Error message

Only named functions are supported

What it means

visit_Call (expr.py:667) first handles ast.Attribute funcs (like obj.method()) and then requires the func to be an ast.Name. If node.func is anything else (a Lambda expression, a parenthesized expression, a subscript result being called), there is no callable name to resolve, so TypeError is raised. The eval grammar supports named functions and attribute calls only.

Source

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

            else:
                resolved = visited_value(self.env)
            try:
                v = getattr(resolved, attr)
                name = self.env.add_tmp(v)
                return self.term_type(name, self.env)
            except AttributeError:
                # something like datetime.datetime where scope is overridden
                if isinstance(value, ast.Name) and value.id == attr:
                    return resolved
                raise

        raise ValueError(f"Invalid Attribute context {type(ctx).__name__}")

    def visit_Call(self, node, side=None, **kwargs):
        if isinstance(node.func, ast.Attribute) and node.func.attr != "__call__":
            res = self.visit_Attribute(node.func)
        elif not isinstance(node.func, ast.Name):
            raise TypeError("Only named functions are supported")
        else:
            try:
                res = self.visit(node.func)
            except UndefinedVariableError:
                # Check if this is a supported function name
                try:
                    res = FuncNode(node.func.id)
                except ValueError:
                    # Raise original error
                    raise

        if res is None:
            # error: "expr" has no attribute "id"
            raise ValueError(
                f"Invalid function call {node.func.id}"  # type: ignore[union-attr]
            )
        if hasattr(res, "value"):
            res = res.value

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Define the function as a named callable and reference it by name (works only if registered in scope).
  2. Compute the transformation in plain Python and assign the result back to a column.
  3. For math, use the supported named functions (sin, cos, log, abs, sqrt, ...).

Example fix

// before
df.eval('(lambda x: x + 1)(a)')
// after
df['a'] = df['a'].map(lambda x: x + 1)
Defensive patterns

Strategy: validation

Validate before calling

import ast

def validate_call_target_is_name_or_attr(expr: str) -> None:
    for node in ast.walk(ast.parse(expr, mode='eval')):
        if isinstance(node, ast.Call):
            if not isinstance(node.func, (ast.Name, ast.Attribute)):
                raise TypeError(
                    'only named functions or attribute calls are supported in eval'
                )

validate_call_target_is_name_or_attr(expr)

Type guard

import ast

def calls_are_named(expr: str) -> bool:
    return all(
        isinstance(n.func, (ast.Name, ast.Attribute))
        for n in ast.walk(ast.parse(expr, mode='eval'))
        if isinstance(n, ast.Call)
    )

Try / catch

try:
    df.eval(expr)
except TypeError as e:
    if 'Only named functions' in str(e):
        # evaluate the transformation in Python instead
        df['result'] = df['a'].map(some_fn)
    raise

Prevention

When it happens

Trigger: df.eval('(lambda x: x + 1)(a)'), df.eval('(f or g)(a)'), or calling the result of any non-Name, non-Attribute expression.

Common situations: Trying to inline lambdas or higher-order calls in an eval string. Porting functional-style Python into eval.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/aa9d169f39a562d3. Report an issue: GitHub.