diff --git a/mypy/checker.py b/mypy/checker.py index 851f23185f4f..b8898f1ebf32 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2376,7 +2376,20 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type self.check_indexed_assignment(index_lvalue, rvalue, lvalue) if inferred: - rvalue_type = self.expr_checker.accept(rvalue) + type_hint = None + if isinstance(lvalue, RefExpr): + inferred_node = lvalue.node + if (isinstance(inferred_node, Var) and + lvalue.kind in (MDEF, None) and # None for Vars defined via self + len(inferred_node.info.bases) > 0): + for base in inferred_node.info.mro[1:]: + base_type, base_node = self.lvalue_type_from_base(inferred_node, base) + + if base_type: + type_hint = base_type + break + + rvalue_type = self.expr_checker.accept(rvalue, type_hint) if not inferred.is_final: rvalue_type = remove_instance_last_known_values(rvalue_type) self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue) diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 4de6e4a76f92..f2f5424a98bf 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -2813,8 +2813,8 @@ class C(A): x = ['12'] reveal_type(A.x) # N: Revealed type is "builtins.list[Any]" -reveal_type(B.x) # N: Revealed type is "builtins.list[builtins.int]" -reveal_type(C.x) # N: Revealed type is "builtins.list[builtins.str]" +reveal_type(B.x) # N: Revealed type is "builtins.list[Any]" +reveal_type(C.x) # N: Revealed type is "builtins.list[Any]" [builtins fixtures/list.pyi] @@ -3255,3 +3255,20 @@ reveal_type(x) # N: Revealed type is "builtins.bytes*" if x: reveal_type(x) # N: Revealed type is "builtins.bytes*" [builtins fixtures/dict.pyi] + +[case testInferHintFromBase] +from typing import Union, List + +class A: pass +class B: pass + +U = Union[A, B] + +class Base: + variable1 : List[U] = [] + variable2 : List[U] = [] + +class Derived(Base): + variable1 = [A()] + variable2 = variable1 +[out]