@@ -303,7 +303,7 @@ class B(A): pass
303303 return cast (F , func )
304304 self_param_type = get_proper_type (func .arg_types [0 ])
305305
306- variables : Sequence [TypeVarLikeType ] = []
306+ variables : Sequence [TypeVarLikeType ]
307307 if func .variables and supported_self_type (self_param_type ):
308308 from mypy .infer import infer_type_arguments
309309
@@ -312,46 +312,40 @@ class B(A): pass
312312 original_type = erase_to_bound (self_param_type )
313313 original_type = get_proper_type (original_type )
314314
315- all_ids = func .type_var_ids ()
315+ # Find which of method type variables appear in the type of "self".
316+ self_ids = {tv .id for tv in get_all_type_vars (self_param_type )}
317+ self_vars = [tv for tv in func .variables if tv .id in self_ids ]
318+
319+ # Solve for these type arguments using the actual class or instance type.
316320 typeargs = infer_type_arguments (
317- func . variables , self_param_type , original_type , is_supertype = True
321+ self_vars , self_param_type , original_type , is_supertype = True
318322 )
319323 if (
320324 is_classmethod
321- # TODO: why do we need the extra guards here?
322325 and any (isinstance (get_proper_type (t ), UninhabitedType ) for t in typeargs )
323326 and isinstance (original_type , (Instance , TypeVarType , TupleType ))
324327 ):
325- # In case we call a classmethod through an instance x, fallback to type(x)
328+ # In case we call a classmethod through an instance x, fallback to type(x).
326329 typeargs = infer_type_arguments (
327- func . variables , self_param_type , TypeType (original_type ), is_supertype = True
330+ self_vars , self_param_type , TypeType (original_type ), is_supertype = True
328331 )
329332
330- ids = [tid for tid in all_ids if any (tid == t .id for t in get_type_vars (self_param_type ))]
331-
332- # Technically, some constrains might be unsolvable, make them <nothing>.
333+ # Update the method signature with the solutions found.
334+ # Technically, some constraints might be unsolvable, make them <nothing>.
333335 to_apply = [t if t is not None else UninhabitedType () for t in typeargs ]
334-
335- def expand (target : Type ) -> Type :
336- return expand_type (target , {id : to_apply [all_ids .index (id )] for id in ids })
337-
338- arg_types = [expand (x ) for x in func .arg_types [1 :]]
339- ret_type = expand (func .ret_type )
340- variables = [v for v in func .variables if v .id not in ids ]
336+ func = expand_type (func , {tv .id : arg for tv , arg in zip (self_vars , to_apply )})
337+ variables = [v for v in func .variables if v not in self_vars ]
341338 else :
342- arg_types = func .arg_types [1 :]
343- ret_type = func .ret_type
344339 variables = func .variables
345340
346341 original_type = get_proper_type (original_type )
347342 if isinstance (original_type , CallableType ) and original_type .is_type_obj ():
348343 original_type = TypeType .make_normalized (original_type .ret_type )
349344 res = func .copy_modified (
350- arg_types = arg_types ,
345+ arg_types = func . arg_types [ 1 :] ,
351346 arg_kinds = func .arg_kinds [1 :],
352347 arg_names = func .arg_names [1 :],
353348 variables = variables ,
354- ret_type = ret_type ,
355349 bound_args = [original_type ],
356350 )
357351 return cast (F , res )
0 commit comments