pandas-dev/pandas · error · SyntaxError
can only assign a single expression
Error message
can only assign a single expression
What it means
visit_Assign (expr.py:613) handles exactly one target: len(node.targets) != 1 raises. Python's AST gives chained assignment 'a = b = 1' two targets and tuple-target assignment 'a, b = ...' a single Tuple target, both of which are rejected. The eval grammar intentionally supports only 'name = expr'.
Source
Thrown at pandas/core/computation/expr.py:624
upper = self.visit(upper).value
step = node.step
if step is not None:
step = self.visit(step).value
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)
View on GitHub (pinned to 71959b8cb9)
Solutions
- Split into separate single-target assignments, one per line: df.eval('a = 1\nb = 2').
- Compute the values in plain Python and assign columns directly.
- Use a multi-line df.eval string where each line is a single assignment.
Example fix
// before
df.eval('a = b = 1')
// after
df.eval('a = 1\nb = 1') Defensive patterns
Strategy: validation
Validate before calling
import ast
def validate_single_target_assignment(expr: str) -> None:
for stmt in ast.parse(expr, mode='exec').body:
if isinstance(stmt, ast.Assign) and len(stmt.targets) != 1:
raise SyntaxError(
f'only single-target assignment supported; split: {expr!r}'
)
validate_single_target_assignment(expr) Type guard
import ast
def uses_only_single_assignments(expr: str) -> bool:
return all(
not isinstance(s, ast.Assign) or len(s.targets) == 1
for s in ast.parse(expr, mode='exec').body
) Try / catch
try:
df.eval(expr)
except SyntaxError as e:
if 'single expression' in str(e) and '=' in expr:
# rewrite 'a = b = v' into 'a = v\nb = v'
df.eval(expr.replace('=', '=...').replace('=', '='))
raise Prevention
- Write one assignment target per line in multi-line eval strings.
- Never use chained 'a = b = v' or tuple unpacking in eval.
- Validate programmatically generated assignments with ast.parse.
When it happens
Trigger: df.eval('a = b = 1'), df.eval('a, b = (1, 2)'), or any assignment form Python parses into multiple targets.
Common situations: Trying to initialize several columns at once. Porting Python chained assignment idioms into eval. Templating systems that emit multi-target assignments.
Related errors
- left hand side of an assignment must be a single name
- multi-line expressions are only valid in the context of data
- Multi-line expressions are only valid if all expressions con
- Cannot operate inplace if there is no assignment
- Cannot assign expression output to target
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/c21a70eddc9a268a.
Report an issue: GitHub.