@@ -69,11 +69,6 @@ def is_subtype(left: Type, right: Type,
69
69
elif is_subtype_of_item :
70
70
return True
71
71
# otherwise, fall through
72
- # Treat builtins.type the same as Type[Any]
73
- elif is_named_instance (left , 'builtins.type' ):
74
- return is_subtype (TypeType (AnyType ()), right )
75
- elif is_named_instance (right , 'builtins.type' ):
76
- return is_subtype (left , TypeType (AnyType ()))
77
72
return left .accept (SubtypeVisitor (right , type_parameter_checker ,
78
73
ignore_pos_arg_names = ignore_pos_arg_names ))
79
74
@@ -158,16 +153,18 @@ def visit_instance(self, left: Instance) -> bool:
158
153
item = right .item
159
154
if isinstance (item , TupleType ):
160
155
item = item .fallback
161
- if isinstance (item , Instance ):
162
- return is_subtype (left , item .type .metaclass_type )
163
- elif isinstance (item , AnyType ):
164
- # Special case: all metaclasses are subtypes of Type[Any]
165
- mro = left .type .mro or []
166
- return any (base .fullname () == 'builtins.type' for base in mro )
167
- else :
168
- return False
169
- else :
170
- return False
156
+ if is_named_instance (left , 'builtins.type' ):
157
+ return is_subtype (TypeType (AnyType ()), right )
158
+ if left .type .is_metaclass ():
159
+ if isinstance (item , AnyType ):
160
+ return True
161
+ if isinstance (item , Instance ):
162
+ # Special-case enum since we don't have better way of expressing it
163
+ if (is_named_instance (left , 'enum.EnumMeta' )
164
+ and is_named_instance (item , 'enum.Enum' )):
165
+ return True
166
+ return is_named_instance (item , 'builtins.object' )
167
+ return False
171
168
172
169
def visit_type_var (self , left : TypeVarType ) -> bool :
173
170
right = self .right
@@ -263,8 +260,8 @@ def visit_overloaded(self, left: Overloaded) -> bool:
263
260
elif isinstance (right , TypeType ):
264
261
# All the items must have the same type object status, so
265
262
# it's sufficient to query only (any) one of them.
266
- # This is unsound, we don't check the __init__ signature .
267
- return left .is_type_obj () and is_subtype (left .items ()[0 ]. ret_type , right . item )
263
+ # This is unsound, we don't check all the __init__ signatures .
264
+ return left .is_type_obj () and is_subtype (left .items ()[0 ], right )
268
265
else :
269
266
return False
270
267
@@ -284,11 +281,14 @@ def visit_type_type(self, left: TypeType) -> bool:
284
281
# This is unsound, we don't check the __init__ signature.
285
282
return is_subtype (left .item , right .ret_type )
286
283
if isinstance (right , Instance ):
287
- if right .type .fullname () == 'builtins.object' :
288
- # treat builtins.object the same as Any.
284
+ if right .type .fullname () in ['builtins.object' , 'builtins.type' ]:
289
285
return True
290
286
item = left .item
291
- return isinstance (item , Instance ) and is_subtype (item , right .type .metaclass_type )
287
+ if isinstance (item , TypeVarType ):
288
+ item = item .upper_bound
289
+ if isinstance (item , Instance ):
290
+ metaclass = item .type .metaclass_type
291
+ return metaclass is not None and is_subtype (metaclass , right )
292
292
return False
293
293
294
294
0 commit comments