From 57a2586589c1699f341e8f1a3a6f7f187f47a8db Mon Sep 17 00:00:00 2001 From: STerliakov Date: Fri, 7 Nov 2025 17:20:09 +0100 Subject: [PATCH 1/2] Do not push partial types to binder --- mypy/checker.py | 8 +++++++- test-data/unit/check-redefine2.test | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 9f8299e6805d..1871816d4148 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3311,6 +3311,7 @@ def check_assignment( # Partial type can't be final, so strip any literal values. rvalue_type = remove_instance_last_known_values(rvalue_type) inferred_type = make_simplified_union([rvalue_type, NoneType()]) + self.binder.put(lvalue, inferred_type) self.set_inferred_type(var, lvalue, inferred_type) else: var.type = None @@ -3373,6 +3374,7 @@ def check_assignment( break if has_if_ancestor: lvalue_type = make_optional_type(lvalue_type) + self.binder.put(lvalue, lvalue_type) self.set_inferred_type(lvalue.node, lvalue, lvalue_type) rvalue_type, lvalue_type = self.check_simple_assignment( @@ -3413,7 +3415,11 @@ def check_assignment( and lvalue_type is not None ): lvalue.node.type = remove_instance_last_known_values(lvalue_type) - elif self.options.allow_redefinition_new and lvalue_type is not None: + elif ( + self.options.allow_redefinition_new + and lvalue_type is not None + and not isinstance(lvalue_type, PartialType) + ): # TODO: Can we use put() here? self.binder.assign_type(lvalue, lvalue_type, lvalue_type) diff --git a/test-data/unit/check-redefine2.test b/test-data/unit/check-redefine2.test index 1abe957240b5..4d99aa17f804 100644 --- a/test-data/unit/check-redefine2.test +++ b/test-data/unit/check-redefine2.test @@ -369,6 +369,16 @@ class C4: reveal_type(self.x) # N: Revealed type is "builtins.list[builtins.str]" reveal_type(C4().x) # N: Revealed type is "builtins.list[builtins.str]" + +class C5: + def __init__(self) -> None: + if int(): + self.x = None + return + self.x = [""] + reveal_type(self.x) # N: Revealed type is "builtins.list[builtins.str]" + +reveal_type(C5().x) # N: Revealed type is "Union[builtins.list[builtins.str], None]" [builtins fixtures/list.pyi] [case testNewRedefinePartialGenericTypes] From f8ad206c22ace68bf4ff9d7dafc30d7951b1d5f3 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Fri, 7 Nov 2025 17:27:04 +0100 Subject: [PATCH 2/2] Remove unrelated attempt --- mypy/checker.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 1871816d4148..523093785bbe 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3311,7 +3311,6 @@ def check_assignment( # Partial type can't be final, so strip any literal values. rvalue_type = remove_instance_last_known_values(rvalue_type) inferred_type = make_simplified_union([rvalue_type, NoneType()]) - self.binder.put(lvalue, inferred_type) self.set_inferred_type(var, lvalue, inferred_type) else: var.type = None @@ -3374,7 +3373,6 @@ def check_assignment( break if has_if_ancestor: lvalue_type = make_optional_type(lvalue_type) - self.binder.put(lvalue, lvalue_type) self.set_inferred_type(lvalue.node, lvalue, lvalue_type) rvalue_type, lvalue_type = self.check_simple_assignment(