pandas-dev/pandas · error · ValueError
Invalid Attribute context
Error message
Invalid Attribute context {ctx.__name__} What it means
Raised by PyTablesExprVisitor.visit_Attribute when an AST Attribute node carries a ctx other than ast.Load (e.g. Store or Del). The pytables query visitor only knows how to read attribute values, so a non-Load attribute access is treated as invalid. In practice HDFStore.select(where=...) parses the query in eval mode, which yields Load contexts, so this is an internal guard against malformed/constructed expression trees rather than something users hit through the documented API.
Solutions
- Pass the where clause as a plain string (e.g. HDFStore.select(key, where='index >= 5')) so it is parsed in eval mode and attributes get ast.Load context.
- If you are building/transforming AST nodes for a pytables query, ensure every ast.Attribute uses ctx=ast.Load() before handing the tree to the visitor.
- Avoid attribute-assignment or deletion syntax in a where expression; pytables queries are read-only predicates.
Example fix
// before node = ast.Attribute(value=ast.Name(id='df', ctx=ast.Store()), attr='A', ctx=ast.Store()) visitor.visit(node) # raises: Invalid Attribute context Store // after node = ast.Attribute(value=ast.Name(id='df', ctx=ast.Load()), attr='A', ctx=ast.Load()) visitor.visit(node)
Defensive patterns
Strategy: validation
Validate before calling
import ast
node = <your attribute ast node>
if not isinstance(getattr(node, 'ctx', None), ast.Load):
raise ValueError(f'attribute node must use ast.Load ctx, got {type(node.ctx).__name__}') Type guard
import ast
def is_load_attribute(node) -> bool:
return isinstance(node, ast.Attribute) and isinstance(node.ctx, ast.Load) Try / catch
try:
visitor.visit(attribute_node)
except ValueError as err:
if 'Invalid Attribute context' in str(err):
# rewrite the node with ast.Load ctx or fall back to a string query
...
raise Prevention
- Always parse pytables where clauses from strings via ast.parse(mode='eval') so ctx is Load.
- Never mutate node.ctx on attribute nodes before visiting.
- Keep pytables queries read-only; do not attempt assignment/deletion semantics.
When it happens
Trigger: Constructing a PyTablesExprVisitor and feeding it an ast.Attribute node whose .ctx is ast.Store or ast.Del; passing a hand-built AST (not a plain query string) into the pytables expression path; any code path that mutates node.ctx on an attribute before the visitor runs.
Common situations: Almost never seen from the public pandas API because df.query / HDFStore.select parse strings with ast.parse(mode='eval'). May surface in tests, forks, or code that rewrites AST nodes (e.g. swapping ctx) before evaluation.
Related errors
- cannot process expression
- cannot process expression
- where must be passed as a string, PyTablesExpr, or…
- arithmetic operations are not supported inside an HDFStore…
- Cannot compare of type to column
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/e8fe5365b2bba649.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/pytables.py:520
ctx = type(node.ctx)
if ctx == ast.Load:
# resolve the value
resolved = self.visit(value)
# try to get the value to see if we are another expression
try:
resolved = resolved.value
except AttributeError:
pass
try:
return self.term_type(getattr(resolved, attr), self.env)
except AttributeError:
# something like datetime.datetime where scope is overridden
if isinstance(value, ast.Name) and value.id == attr:
return resolved
raise ValueError(f"Invalid Attribute context {ctx.__name__}")
def translate_In(self, op):
return ast.Eq() if isinstance(op, ast.In) else op
def _rewrite_membership_op(self, node, left, right):
return self.visit(node.op), node.op, left, right
def _validate_where(w):
"""
Validate that the where statement is of the right type.
The type may either be String, Expr, or list-like of Exprs.
Parameters
----------
w : String term expression, Expr, or list-like of Exprs.
View on GitHub (pinned to 3b7651241d)