pandas-dev/pandas · error · ValueError
Cannot operate inplace if there is no assignment
Error message
Cannot operate inplace if there is no assignment
What it means
inplace=True tells pandas to mutate the target rather than return a copy. With no assignment in the expression (parsed_expr.assigner is None at eval.py:402), there is nothing to mutate, so inplace is meaningless and pandas refuses rather than silently no-op. The check sits in the assigner-is-None branch alongside the multi-line check.
Source
Thrown at pandas/core/computation/eval.py:409
"extension array dtypes. Please set your engine to python manually.",
RuntimeWarning,
stacklevel=find_stack_level(),
)
engine = "python"
# construct the engine and evaluate the parsed expression
eng = ENGINES[engine]
eng_inst = eng(parsed_expr)
ret = eng_inst.evaluate()
if parsed_expr.assigner is None:
if multi_line:
raise ValueError(
"Multi-line expressions are only valid "
"if all expressions contain an assignment"
)
if inplace:
raise ValueError("Cannot operate inplace if there is no assignment")
# assign if needed
assigner = parsed_expr.assigner
if env.target is not None and assigner is not None:
target_modified = True
# if returning a copy, copy only on the first assignment
if not inplace and first_expr:
try:
target = env.target
if isinstance(target, NDFrame):
target = target.copy(deep=False)
else:
target = target.copy()
except AttributeError as err:
raise ValueError("Cannot return a copy of the target") from err
else:
target = env.targetView on GitHub (pinned to 71959b8cb9)
Solutions
- Drop inplace=True for read-only expressions and use the returned Series/frame.
- Add an assignment to make the expression mutative: df.eval('c = a + b', inplace=True).
- Use df.loc or direct column assignment if you want to store the result.
Example fix
// before
df.eval('a + b', inplace=True)
// after
df.eval('c = a + b', inplace=True) Defensive patterns
Strategy: validation
Validate before calling
def validate_inplace_has_assignment(expr: str, inplace: bool) -> None:
import ast
if inplace:
tree = ast.parse(expr, mode='exec')
if not any(isinstance(n, ast.Assign) for n in tree.body):
raise ValueError(
'inplace=True requires an assignment in the expression'
)
validate_inplace_has_assignment(expr, inplace) Type guard
import ast
def inplace_is_safe(expr: str, inplace: bool) -> bool:
if not inplace:
return True
return any(
isinstance(n, ast.Assign) for n in ast.parse(expr, mode='exec').body
) Try / catch
try:
df.eval(expr, inplace=True)
except ValueError as e:
if 'no assignment' in str(e):
result = df.eval(expr, inplace=False) # fall back to returning
else:
raise Prevention
- Only set inplace=True when the expression assigns a column.
- Default to inplace=False and capture the return value.
- Reserve inplace for 'col = ...' style expressions.
When it happens
Trigger: df.eval('a + b', inplace=True), df.query('a > b', inplace=True) — any read-only expression combined with inplace=True.
Common situations: Setting inplace=True globally by habit or copy-paste. Confusing query (which filters rows) with assignment semantics. Expecting inplace to mean 'cache the result'.
Related errors
- multi-line expressions are only valid in the context of data
- Multi-line expressions are only valid if all expressions con
- Cannot return a copy of the target
- Cannot assign expression output to target
- can only assign a single expression
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/5529d192132d5448.
Report an issue: GitHub.