{"record":{"id":"65f07ed9f466e0f9","repo":"pandas-dev/pandas","slug":"multi-line-expressions-are-only-valid-if-all-expre","errorCode":null,"errorMessage":"Multi-line expressions are only valid if all expressions contain an assignment","messagePattern":"Multi-line expressions are only valid if all expressions contain an assignment","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/eval.py","lineNumber":404,"sourceCode":"                )\n            )\n        ):\n            warnings.warn(\n                \"Engine has switched to 'python' because numexpr does not support \"\n                \"extension array dtypes. Please set your engine to python manually.\",\n                RuntimeWarning,\n                stacklevel=find_stack_level(),\n            )\n            engine = \"python\"\n\n        # construct the engine and evaluate the parsed expression\n        eng = ENGINES[engine]\n        eng_inst = eng(parsed_expr)\n        ret = eng_inst.evaluate()\n\n        if parsed_expr.assigner is None:\n            if multi_line:\n                raise ValueError(\n                    \"Multi-line expressions are only valid \"\n                    \"if all expressions contain an assignment\"\n                )\n            if inplace:\n                raise ValueError(\"Cannot operate inplace if there is no assignment\")\n\n        # assign if needed\n        assigner = parsed_expr.assigner\n        if env.target is not None and assigner is not None:\n            target_modified = True\n\n            # if returning a copy, copy only on the first assignment\n            if not inplace and first_expr:\n                try:\n                    target = env.target\n                    if isinstance(target, NDFrame):\n                        target = target.copy(deep=False)\n                    else:","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/computation/eval.py#L386-L422","documentation":"Raised after evaluation when parsed_expr.assigner is None (i.e., the expression has no top-level assignment) but multi_line is True. In a multi-line expression every line must contain an assignment (e.g., 'c = a + b'); a bare expression line like 'a + 2' has no assigner, so the multi-line contract is violated. This catches inconsistent multi-line input where some lines assign and some do not.","triggerScenarios":"Calling df.eval('a = b + 1\\na + 2') — the second line 'a + 2' has no assignment, so assigner is None and multi_line is True.","commonSituations":"Building a multi-line expression programmatically and appending a final 'return' or display line that is a bare expression; copy-pasting a sequence of computations where the last line was meant as output rather than an assignment.","solutions":["Ensure every line in a multi-line eval contains an assignment: df.eval('a = b + 1\\nc = a + 2').","If you need the final value returned, split into separate calls: assign all columns, then read the result separately.","Remove the non-assigning line if it was unintentional."],"exampleFix":"// before\ndf.eval('a = b + 1\\na + 2')\n\n// after\ndf.eval('a = b + 1\\nc = a + 2')","handlingStrategy":"validation","validationCode":"import re\ndef all_lines_assign(expr: str) -> bool:\n    lines = [l.strip() for l in expr.splitlines() if l.strip()]\n    return all(re.search(r'^[A-Za-z_]\\w*\\s*=', l) for l in lines)\n\nif not all_lines_assign(expr):\n    raise ValueError('Every line must contain an assignment')\ndf.eval(expr)","typeGuard":null,"tryCatchPattern":"try:\n    df.eval(expr)\nexcept ValueError as e:\n    if 'must contain an assignment' in str(e):\n        # rewrite or split lines\n        ...","preventionTips":["Format multi-line eval as one assignment per line.","Avoid appending bare display lines to assignment lists.","Validate programmatically-built expressions before eval."],"tags":["pandas","eval","multiline","assignment","validation"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}