44import mypy .sametypes
55from mypy .expandtype import expand_type
66from mypy .types import (
7- Type , TypeVarId , TypeVarType , CallableType , AnyType , PartialType , get_proper_types
7+ Type , TypeVarId , TypeVarType , CallableType , AnyType , PartialType , get_proper_types ,
8+ TypeVarDef , TypeVarLikeDef , ProperType
89)
910from mypy .nodes import Context
1011
@@ -29,20 +30,23 @@ def apply_generic_arguments(
2930 # Check that inferred type variable values are compatible with allowed
3031 # values and bounds. Also, promote subtype values to allowed values.
3132 types = get_proper_types (orig_types )
32- for i , type in enumerate (types ):
33- assert not isinstance (type , PartialType ), "Internal error: must never apply partial type"
34- values = get_proper_types (callable .variables [i ].values )
35- if type is None :
36- continue
33+
34+ # Create a map from type variable id to target type.
35+ id_to_type = {} # type: Dict[TypeVarId, Type]
36+
37+ def get_target_type (tvar : TypeVarLikeDef , type : ProperType ) -> Optional [Type ]:
38+ # TODO(shantanu): fix for ParamSpecDef
39+ assert isinstance (tvar , TypeVarDef )
40+ values = get_proper_types (tvar .values )
3741 if values :
3842 if isinstance (type , AnyType ):
39- continue
43+ return type
4044 if isinstance (type , TypeVarType ) and type .values :
4145 # Allow substituting T1 for T if every allowed value of T1
4246 # is also a legal value of T.
4347 if all (any (mypy .sametypes .is_same_type (v , v1 ) for v in values )
4448 for v1 in type .values ):
45- continue
49+ return type
4650 matching = []
4751 for value in values :
4852 if mypy .subtypes .is_subtype (type , value ):
@@ -53,28 +57,26 @@ def apply_generic_arguments(
5357 for match in matching [1 :]:
5458 if mypy .subtypes .is_subtype (match , best ):
5559 best = match
56- types [i ] = best
57- else :
58- if skip_unsatisfied :
59- types [i ] = None
60- else :
61- report_incompatible_typevar_value (callable , type , callable .variables [i ].name ,
62- context )
60+ return best
61+ if skip_unsatisfied :
62+ return None
63+ report_incompatible_typevar_value (callable , type , tvar .name , context )
6364 else :
64- upper_bound = callable . variables [ i ] .upper_bound
65+ upper_bound = tvar .upper_bound
6566 if not mypy .subtypes .is_subtype (type , upper_bound ):
6667 if skip_unsatisfied :
67- types [i ] = None
68- else :
69- report_incompatible_typevar_value (callable , type , callable .variables [i ].name ,
70- context )
68+ return None
69+ report_incompatible_typevar_value (callable , type , tvar .name , context )
70+ return type
7171
72- # Create a map from type variable id to target type.
73- id_to_type = {} # type: Dict[TypeVarId, Type]
74- for i , tv in enumerate (tvars ):
75- typ = types [i ]
76- if typ :
77- id_to_type [tv .id ] = typ
72+ for tvar , type in zip (tvars , types ):
73+ assert not isinstance (type , PartialType ), "Internal error: must never apply partial type"
74+ if type is None :
75+ continue
76+
77+ target_type = get_target_type (tvar , type )
78+ if target_type is not None :
79+ id_to_type [tvar .id ] = target_type
7880
7981 # Apply arguments to argument types.
8082 arg_types = [expand_type (at , id_to_type ) for at in callable .arg_types ]
0 commit comments