pandas-dev/pandas · error · ValueError
cannot assign without a target object
Error message
cannot assign without a target object
What it means
visit_Assign checks self.env.target at expr.py:627; if None it raises ValueError. The target is what receives the assignment (target[assigner] = ret at eval.py:437). DataFrame.eval supplies the frame as target automatically, but pd.eval does not — it defaults to target=None.
Source
Thrown at pandas/core/computation/expr.py:628
return slice(lower, upper, step)
def visit_Assign(self, node, **kwargs):
"""
support a single assignment node, like
c = a + b
set the assigner at the top level, must be a Name node which
might or might not exist in the resolvers
"""
if len(node.targets) != 1:
raise SyntaxError("can only assign a single expression")
if not isinstance(node.targets[0], ast.Name):
raise SyntaxError("left hand side of an assignment must be a single name")
if self.env.target is None:
raise ValueError("cannot assign without a target object")
try:
assigner = self.visit(node.targets[0], **kwargs)
except UndefinedVariableError:
assigner = node.targets[0].id
self.assigner = getattr(assigner, "name", assigner)
if self.assigner is None:
raise SyntaxError(
"left hand side of an assignment must be a single resolvable name"
)
return self.visit(node.value, **kwargs)
def visit_Attribute(self, node, **kwargs):
attr = node.attr
value = node.value
View on GitHub (pinned to 71959b8cb9)
Solutions
- Use df.eval('a = b + 1') so the frame is the implicit target.
- Pass target explicitly: pd.eval('a = b + 1', target=df).
- Pass a dict target if you want the result collected into a namespace.
Example fix
// before
pd.eval('a = b + 1')
// after
df.eval('a = b + 1') Defensive patterns
Strategy: validation
Validate before calling
import ast
def ensure_target_for_assignment(expr: str, target) -> None:
has_assign = any(
isinstance(s, ast.Assign)
for s in ast.parse(expr, mode='exec').body
)
if has_assign and target is None:
raise ValueError(
'assignment expression requires a target; use df.eval or pass target='
)
ensure_target_for_assignment(expr, target) Type guard
import ast
def assignment_has_target(expr: str, target) -> bool:
has_assign = any(
isinstance(s, ast.Assign) for s in ast.parse(expr, mode='exec').body
)
return not has_assign or target is not None Try / catch
try:
pd.eval(expr)
except ValueError as e:
if 'without a target' in str(e):
df.eval(expr) # switch to DataFrame.eval for the implicit target
else:
raise Prevention
- Use DataFrame.eval for any assignment expression.
- If calling pd.eval with an assignment, always pass target=.
- Wrap assignment eval calls in a helper that injects the frame as target.
When it happens
Trigger: pd.eval('a = b + 1') with no target kwarg. Any assignment expression routed through pd.eval instead of DataFrame.eval without supplying target.
Common situations: Using pd.eval generically for assignments instead of df.eval. Refactoring df.eval calls into pd.eval and forgetting to forward target.
Related errors
- multi-line expressions are only valid in the context of data
- Cannot assign expression output to target
- Multi-line expressions are only valid if all expressions con
- Cannot operate inplace if there is no assignment
- Cannot return a copy of the target
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/ad5c0bc6b8c8942e.
Report an issue: GitHub.