@@ -2091,6 +2091,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
2091
2091
infer_lvalue_type )
2092
2092
else :
2093
2093
self .try_infer_partial_generic_type_from_assignment (lvalue , rvalue , '=' )
2094
+ self .try_infer_partial_generic_type_from_super (lvalue , rvalue )
2094
2095
lvalue_type , index_lvalue , inferred = self .check_lvalue (lvalue )
2095
2096
# If we're assigning to __getattr__ or similar methods, check that the signature is
2096
2097
# valid.
@@ -2241,6 +2242,40 @@ def try_infer_partial_generic_type_from_assignment(self,
2241
2242
var .type = fill_typevars_with_any (typ .type )
2242
2243
del partial_types [var ]
2243
2244
2245
+ def try_infer_partial_generic_type_from_super (self , lvalue : Lvalue ,
2246
+ rvalue : Expression ) -> None :
2247
+ """Try to infer a precise type for partial generic type from super types.
2248
+
2249
+ Example where this happens:
2250
+
2251
+ class P:
2252
+ x: List[int]
2253
+
2254
+ class C(P):
2255
+ x = [] # Infer List[int] as type of 'x'
2256
+
2257
+ """
2258
+ var = None
2259
+ if (isinstance (lvalue , NameExpr )
2260
+ and isinstance (lvalue .node , Var )
2261
+ and lvalue .node .type is None ):
2262
+ var = lvalue .node
2263
+ self .infer_partial_type (var , lvalue ,
2264
+ self .expr_checker .accept (rvalue ))
2265
+
2266
+ if var is not None :
2267
+ partial_types = self .find_partial_types (var )
2268
+ if partial_types is None :
2269
+ return
2270
+
2271
+ parent_type = self .get_defined_in_base_class (var )
2272
+ if parent_type is not None and is_valid_inferred_type (parent_type ):
2273
+ self .set_inferred_type (var , lvalue , parent_type )
2274
+ if isinstance (lvalue , RefExpr ):
2275
+ # We need this to escape another round of inference:
2276
+ lvalue .is_inferred_def = False
2277
+ del partial_types [var ]
2278
+
2244
2279
def check_compatibility_all_supers (self , lvalue : RefExpr , lvalue_type : Optional [Type ],
2245
2280
rvalue : Expression ) -> bool :
2246
2281
lvalue_node = lvalue .node
@@ -4870,12 +4905,6 @@ def enter_partial_types(self, *, is_function: bool = False,
4870
4905
and not permissive ):
4871
4906
var .type = NoneType ()
4872
4907
else :
4873
- if is_class :
4874
- # Special case: possibly super-type defines the type for us?
4875
- parent_type = self .get_defined_in_base_class (var )
4876
- if parent_type is not None :
4877
- var .type = parent_type
4878
- self .partial_reported .add (var )
4879
4908
if var not in self .partial_reported and not permissive :
4880
4909
self .msg .need_annotation_for_var (var , context , self .options .python_version )
4881
4910
self .partial_reported .add (var )
0 commit comments