pandas-dev/pandas · error · SyntaxError
left hand side of an assignment must be a single name
Error message
left hand side of an assignment must be a single name
What it means
visit_Assign requires the single target to be an ast.Name (expr.py:625). Subscript assignment ('a[0] = 1') yields an ast.Subscript target and attribute assignment ('a.b = 1') yields an ast.Attribute target, both rejected. Only plain identifier LHS is supported because the assignment path writes target[assigner] = ret with a string key.
Source
Thrown at pandas/core/computation/expr.py:626
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)
def visit_Attribute(self, node, **kwargs):
attr = node.attrView on GitHub (pinned to 71959b8cb9)
Solutions
- Assign to a column name directly: df.eval('new_col = a + b').
- Do cell-level or attribute-level assignment in plain Python (df.loc[i, 'a'] = 1).
- Compute the value with eval and assign the result outside the string.
Example fix
// before
df.eval('a[0] = 1')
// after
df.loc[0, 'a'] = 1 Defensive patterns
Strategy: validation
Validate before calling
import ast
def validate_lhs_is_name(expr: str) -> None:
for stmt in ast.parse(expr, mode='exec').body:
if isinstance(stmt, ast.Assign) and not isinstance(stmt.targets[0], ast.Name):
raise SyntaxError(
'assignment LHS must be a plain name, not a subscript or attribute'
)
validate_lhs_is_name(expr) Type guard
import ast
def lhs_is_plain_name(expr: str) -> bool:
return all(
not isinstance(s, ast.Assign) or isinstance(s.targets[0], ast.Name)
for s in ast.parse(expr, mode='exec').body
) Try / catch
try:
df.eval(expr)
except SyntaxError as e:
if 'single name' in str(e):
# do the indexed/attr assignment in Python instead
df.loc[i, 'a'] = value
raise Prevention
- Use only plain column names on the LHS of eval assignments.
- Perform cell-level or attribute-level writes via the object API.
- Compute RHS in eval and assign outside when LHS must be indexed.
When it happens
Trigger: df.eval('a[0] = 1'), df.eval('a.b = 1'), df.eval('a["x"] = 1'), or any LHS that is not a bare identifier.
Common situations: Trying to update a single cell or a nested attribute via eval. Porting indexing assignments into the string grammar.
Related errors
- can only assign a single expression
- 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/d7b62d8d83b0188b.
Report an issue: GitHub.