3636
3737def check_type_parameter (lefta : Type , righta : Type , variance : int ) -> bool :
3838 if variance == COVARIANT :
39- return is_subtype (lefta , righta , check_type_parameter )
39+ return is_subtype (lefta , righta )
4040 elif variance == CONTRAVARIANT :
41- return is_subtype (righta , lefta , check_type_parameter )
41+ return is_subtype (righta , lefta )
4242 else :
43- return is_equivalent (lefta , righta , check_type_parameter )
43+ return is_equivalent (lefta , righta )
44+
45+
46+ def ignore_type_parameter (s : Type , t : Type , v : int ) -> bool :
47+ return True
4448
4549
4650def is_subtype (left : Type , right : Type ,
47- type_parameter_checker : Optional [TypeParameterChecker ] = None ,
48- * , ignore_pos_arg_names : bool = False ,
51+ * ,
52+ ignore_type_params : bool = False ,
53+ ignore_pos_arg_names : bool = False ,
4954 ignore_declared_variance : bool = False ,
5055 ignore_promotions : bool = False ) -> bool :
5156 """Is 'left' subtype of 'right'?
@@ -59,15 +64,15 @@ def is_subtype(left: Type, right: Type,
5964 between the type arguments (e.g., A and B), taking the variance of the
6065 type var into account.
6166 """
62- type_parameter_checker = type_parameter_checker or check_type_parameter
6367 if (isinstance (right , AnyType ) or isinstance (right , UnboundType )
6468 or isinstance (right , ErasedType )):
6569 return True
6670 elif isinstance (right , UnionType ) and not isinstance (left , UnionType ):
6771 # Normally, when 'left' is not itself a union, the only way
6872 # 'left' can be a subtype of the union 'right' is if it is a
6973 # subtype of one of the items making up the union.
70- is_subtype_of_item = any (is_subtype (left , item , type_parameter_checker ,
74+ is_subtype_of_item = any (is_subtype (left , item ,
75+ ignore_type_params = ignore_type_params ,
7176 ignore_pos_arg_names = ignore_pos_arg_names ,
7277 ignore_declared_variance = ignore_declared_variance ,
7378 ignore_promotions = ignore_promotions )
@@ -83,69 +88,65 @@ def is_subtype(left: Type, right: Type,
8388 elif is_subtype_of_item :
8489 return True
8590 # otherwise, fall through
86- return left .accept (SubtypeVisitor (right , type_parameter_checker ,
91+ return left .accept (SubtypeVisitor (right ,
92+ ignore_type_params = ignore_type_params ,
8793 ignore_pos_arg_names = ignore_pos_arg_names ,
8894 ignore_declared_variance = ignore_declared_variance ,
8995 ignore_promotions = ignore_promotions ))
9096
9197
9298def is_subtype_ignoring_tvars (left : Type , right : Type ) -> bool :
93- def ignore_tvars (s : Type , t : Type , v : int ) -> bool :
94- return True
95- return is_subtype (left , right , ignore_tvars )
99+ return is_subtype (left , right , ignore_type_params = True )
96100
97101
98- def is_equivalent (a : Type ,
99- b : Type ,
100- type_parameter_checker : Optional [TypeParameterChecker ] = None ,
102+ def is_equivalent (a : Type , b : Type ,
101103 * ,
104+ ignore_type_params : bool = False ,
102105 ignore_pos_arg_names : bool = False
103106 ) -> bool :
104107 return (
105- is_subtype (a , b , type_parameter_checker , ignore_pos_arg_names = ignore_pos_arg_names )
106- and is_subtype (b , a , type_parameter_checker , ignore_pos_arg_names = ignore_pos_arg_names ))
108+ is_subtype (a , b , ignore_type_params = ignore_type_params ,
109+ ignore_pos_arg_names = ignore_pos_arg_names )
110+ and is_subtype (b , a , ignore_type_params = ignore_type_params ,
111+ ignore_pos_arg_names = ignore_pos_arg_names ))
107112
108113
109114class SubtypeVisitor (TypeVisitor [bool ]):
110115
111116 def __init__ (self , right : Type ,
112- type_parameter_checker : TypeParameterChecker ,
113- * , ignore_pos_arg_names : bool = False ,
117+ * ,
118+ ignore_type_params : bool ,
119+ ignore_pos_arg_names : bool = False ,
114120 ignore_declared_variance : bool = False ,
115121 ignore_promotions : bool = False ) -> None :
116122 self .right = right
117- self .check_type_parameter = type_parameter_checker
123+ self .ignore_type_params = ignore_type_params
118124 self .ignore_pos_arg_names = ignore_pos_arg_names
119125 self .ignore_declared_variance = ignore_declared_variance
120126 self .ignore_promotions = ignore_promotions
127+ self .check_type_parameter = (ignore_type_parameter if ignore_type_params else
128+ check_type_parameter )
121129 self ._subtype_kind = SubtypeVisitor .build_subtype_kind (
122- type_parameter_checker = type_parameter_checker ,
130+ ignore_type_params = ignore_type_params ,
123131 ignore_pos_arg_names = ignore_pos_arg_names ,
124132 ignore_declared_variance = ignore_declared_variance ,
125133 ignore_promotions = ignore_promotions )
126134
127135 @staticmethod
128136 def build_subtype_kind (* ,
129- type_parameter_checker : Optional [ TypeParameterChecker ] = None ,
137+ ignore_type_params : bool = False ,
130138 ignore_pos_arg_names : bool = False ,
131139 ignore_declared_variance : bool = False ,
132140 ignore_promotions : bool = False ) -> SubtypeKind :
133- type_parameter_checker = type_parameter_checker or check_type_parameter
134- return ('subtype' ,
135- type_parameter_checker ,
141+ return (False , # is proper subtype?
142+ ignore_type_params ,
136143 ignore_pos_arg_names ,
137144 ignore_declared_variance ,
138145 ignore_promotions )
139146
140- def _lookup_cache (self , left : Instance , right : Instance ) -> bool :
141- return TypeState .is_cached_subtype_check (self ._subtype_kind , left , right )
142-
143- def _record_cache (self , left : Instance , right : Instance ) -> None :
144- TypeState .record_subtype_cache_entry (self ._subtype_kind , left , right )
145-
146147 def _is_subtype (self , left : Type , right : Type ) -> bool :
147148 return is_subtype (left , right ,
148- type_parameter_checker = self .check_type_parameter ,
149+ ignore_type_params = self .ignore_type_params ,
149150 ignore_pos_arg_names = self .ignore_pos_arg_names ,
150151 ignore_declared_variance = self .ignore_declared_variance ,
151152 ignore_promotions = self .ignore_promotions )
@@ -190,12 +191,12 @@ def visit_instance(self, left: Instance) -> bool:
190191 if isinstance (right , TupleType ) and right .fallback .type .is_enum :
191192 return self ._is_subtype (left , right .fallback )
192193 if isinstance (right , Instance ):
193- if self . _lookup_cache ( left , right ):
194+ if TypeState . is_cached_subtype_check ( self . _subtype_kind , left , right ):
194195 return True
195196 if not self .ignore_promotions :
196197 for base in left .type .mro :
197198 if base ._promote and self ._is_subtype (base ._promote , self .right ):
198- self . _record_cache ( left , right )
199+ TypeState . record_subtype_cache_entry ( self . _subtype_kind , left , right )
199200 return True
200201 rname = right .type .fullname ()
201202 # Always try a nominal check if possible,
@@ -208,7 +209,7 @@ def visit_instance(self, left: Instance) -> bool:
208209 for lefta , righta , tvar in
209210 zip (t .args , right .args , right .type .defn .type_vars ))
210211 if nominal :
211- self . _record_cache ( left , right )
212+ TypeState . record_subtype_cache_entry ( self . _subtype_kind , left , right )
212213 return nominal
213214 if right .type .is_protocol and is_protocol_implementation (left , right ):
214215 return True
@@ -303,7 +304,8 @@ def visit_typeddict_type(self, left: TypedDictType) -> bool:
303304 if not left .names_are_wider_than (right ):
304305 return False
305306 for name , l , r in left .zip (right ):
306- if not is_equivalent (l , r , self .check_type_parameter ):
307+ if not is_equivalent (l , r ,
308+ ignore_type_params = self .ignore_type_params ):
307309 return False
308310 # Non-required key is not compatible with a required key since
309311 # indexing may fail unexpectedly if a required key is missing.
@@ -1033,13 +1035,7 @@ def __init__(self, right: Type, *, ignore_promotions: bool = False) -> None:
10331035
10341036 @staticmethod
10351037 def build_subtype_kind (* , ignore_promotions : bool = False ) -> SubtypeKind :
1036- return ('subtype_proper' , ignore_promotions )
1037-
1038- def _lookup_cache (self , left : Instance , right : Instance ) -> bool :
1039- return TypeState .is_cached_subtype_check (self ._subtype_kind , left , right )
1040-
1041- def _record_cache (self , left : Instance , right : Instance ) -> None :
1042- TypeState .record_subtype_cache_entry (self ._subtype_kind , left , right )
1038+ return (True , ignore_promotions )
10431039
10441040 def _is_proper_subtype (self , left : Type , right : Type ) -> bool :
10451041 return is_proper_subtype (left , right , ignore_promotions = self .ignore_promotions )
@@ -1073,12 +1069,12 @@ def visit_deleted_type(self, left: DeletedType) -> bool:
10731069 def visit_instance (self , left : Instance ) -> bool :
10741070 right = self .right
10751071 if isinstance (right , Instance ):
1076- if self . _lookup_cache ( left , right ):
1072+ if TypeState . is_cached_subtype_check ( self . _subtype_kind , left , right ):
10771073 return True
10781074 if not self .ignore_promotions :
10791075 for base in left .type .mro :
10801076 if base ._promote and self ._is_proper_subtype (base ._promote , right ):
1081- self . _record_cache ( left , right )
1077+ TypeState . record_subtype_cache_entry ( self . _subtype_kind , left , right )
10821078 return True
10831079
10841080 if left .type .has_base (right .type .fullname ()):
@@ -1095,7 +1091,7 @@ def check_argument(leftarg: Type, rightarg: Type, variance: int) -> bool:
10951091 nominal = all (check_argument (ta , ra , tvar .variance ) for ta , ra , tvar in
10961092 zip (left .args , right .args , right .type .defn .type_vars ))
10971093 if nominal :
1098- self . _record_cache ( left , right )
1094+ TypeState . record_subtype_cache_entry ( self . _subtype_kind , left , right )
10991095 return nominal
11001096 if (right .type .is_protocol and
11011097 is_protocol_implementation (left , right , proper_subtype = True )):
0 commit comments