pandas-dev/pandas · error · ValueError

Invalid Attribute context

Error message

Invalid Attribute context {type(ctx).__name__}

What it means

Raised by visit_Attribute() when the attribute node's context (node.ctx) is not an ast.Load instance. pandas eval only supports reading attributes (Load context, e.g., 'df.col' to read a value); attribute deletion (ast.Del) or attribute storage/assignment (ast.Store) are not supported inside the eval DSL. The message includes the actual context type name for diagnostics.

Solutions

  1. Use attribute access only for reading: df.eval('col_a + df.col_b') where attributes are read-only.
  2. For attribute assignment, do it outside eval: df.col_c = df['col_a'] + df['col_b'].
  3. Restrict eval expressions to Load-context attribute access on resolvable objects.

Example fix

// before
# expression that triggers a non-Load attribute context inside eval

// after
df['col_c'] = df['col_a'] + df['col_b']  # do assignment outside eval
Defensive patterns

Strategy: try-catch

Validate before calling

import ast
def attributes_are_load_only(expr: str) -> bool:
    try:
        tree = ast.parse(expr, mode='eval')
    except SyntaxError:
        return True
    for node in ast.walk(tree):
        if isinstance(node, ast.Attribute) and not isinstance(node.ctx, ast.Load):
            return False
    return True
if not attributes_are_load_only(expr):
    raise ValueError('Attribute store/delete not supported in eval')
df.eval(expr)

Try / catch

try:
    df.eval(expr)
except ValueError as e:
    if 'Invalid Attribute context' in str(e):
        # perform attribute assignment outside eval
        ...

Prevention

When it happens

Trigger: Expressions that attempt attribute assignment or deletion inside eval, producing an ast.Store or ast.Del context rather than ast.Load. Rare since most such attempts are caught earlier by visit_Assign's ast.Name check, but reachable through certain complex attribute expressions.

Common situations: Constructing expressions that use attribute syntax in a storing/deleting context; programmatic AST manipulation that produces non-Load attribute nodes.

Related errors


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

Appendix: source

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

        ctx = node.ctx
        if isinstance(ctx, ast.Load):
            # resolve the value
            visited_value = self.visit(value)
            if hasattr(visited_value, "value"):
                resolved = visited_value.value
            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:

View on GitHub (pinned to 3b7651241d)