From ffe90ad5bf135235b8ec8e6e44985dd6d212a914 Mon Sep 17 00:00:00 2001 From: TheMuffinMan1320 <76186189+TheMuffinMan1320@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:51:13 -0500 Subject: [PATCH] Fix crash on invalid starred assignment target (#20796) `*a = b` (a bare starred assignment target, not wrapped in a list or tuple) is invalid, and semantic analysis already reports "Starred assignment target must be in a list or tuple" for it. However, analyze_lvalue() returned without recursing into the inner name of the StarExpr, so if that name had earlier been registered as a PlaceholderNode (e.g. because the right-hand side referenced an as-yet-undefined name and analysis had to be deferred), the placeholder was never replaced with a real definition. This caused a later crash when writing the incremental cache: `NotImplementedError: Cannot serialize PlaceholderNode instance`. Fix by still analyzing the inner lvalue after reporting the error, so any placeholder gets resolved like it would for a valid nested star target. Fixes #20796 --- mypy/semanal.py | 5 ++--- test-data/unit/check-statements.test | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 7f961687a8aee..0e7cdae426730 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4516,10 +4516,9 @@ def analyze_lvalue( elif isinstance(lval, TupleExpr): self.analyze_tuple_or_list_lvalue(lval, explicit_type) elif isinstance(lval, StarExpr): - if nested: - self.analyze_lvalue(lval.expr, nested, explicit_type) - else: + if not nested: self.fail("Starred assignment target must be in a list or tuple", lval) + self.analyze_lvalue(lval.expr, nested, explicit_type) else: self.fail("Invalid assignment target", lval) diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index cb445cf4a1a2b..f9156b4d1b8c4 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -2104,6 +2104,12 @@ if int(): -- --------------- +[case testInvalidBareStarAssignmentTargetNoCrash] +# https://github.com/python/mypy/issues/20796 +# flags: --debug-serialize +*a = b # E: Starred assignment target must be in a list or tuple \ + # E: Name "b" is not defined + [case testAssignListToStarExpr] from typing import List bs: List[A]