From ab0d79d1d4ef4df2190f50107a998a356dad0f4e Mon Sep 17 00:00:00 2001 From: zhengguangzhuo <100548634+zhengguangzhuo@users.noreply.github.com> Date: Fri, 23 Oct 2026 11:29:36 +0800 Subject: [PATCH] Fix partial assignments with walrus expressions --- mypy/checker.py | 12 ++++++++++++ test-data/unit/check-python38.test | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/mypy/checker.py b/mypy/checker.py index fd4486218dc1..b47a44af26b1 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3538,6 +3538,18 @@ def check_assignment( var.type = None del partial_types[var] lvalue_type = var.type + elif var.type is not None: + # 右值中的 walrus 可能已解析该变量的 partial type, + # 因此仍需检查外层赋值。 + lvalue_type = var.type + self.check_subtype( + rvalue_type, + lvalue_type, + rvalue, + message_registry.INCOMPATIBLE_TYPES_IN_ASSIGNMENT, + "expression has type", + "variable has type", + ) else: # Try to infer a partial type. if not self.infer_partial_type(var, lvalue, rvalue_type): diff --git a/test-data/unit/check-python38.test b/test-data/unit/check-python38.test index 628c40096d94..dc13add45082 100644 --- a/test-data/unit/check-python38.test +++ b/test-data/unit/check-python38.test @@ -821,6 +821,13 @@ i: Optional[int] = 0 if condition() else None x: Optional[tuple[int, int]] = (i, (i := 1)) # E: Incompatible types in assignment (expression has type "tuple[int | None, int]", variable has type "tuple[int, int] | None") [builtins fixtures/tuple.pyi] +[case testPartialTypeWalrusAssignment] +def fn() -> int: + x = None + x = (x, (x := 1)) # E: Incompatible types in assignment (expression has type "tuple[None, int]", variable has type "int | None") + return x +[builtins fixtures/tuple.pyi] + [case testReturnTupleOptionalWalrus] from typing import Optional