Skip to content

Commit 81df467

Browse files
ilevkivskyiddfisher
authored andcommitted
Treat type equivalent to Type[Any] (#2825)
Fixes #2655 As discussed in typing docs, Type[Any] is equivalent to plain type. is_subtype was checking this only one side, here I add the opposite side.
1 parent a8c7947 commit 81df467

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

mypy/subtypes.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def is_subtype(left: Type, right: Type,
5252
return any(is_subtype(left, item, type_parameter_checker,
5353
ignore_pos_arg_names=ignore_pos_arg_names)
5454
for item in right.items)
55+
# Treat builtins.type the same as Type[Any]
56+
elif is_named_instance(left, 'builtins.type'):
57+
return is_subtype(TypeType(AnyType()), right)
58+
elif is_named_instance(right, 'builtins.type'):
59+
return is_subtype(left, TypeType(AnyType()))
5560
else:
5661
return left.accept(SubtypeVisitor(right, type_parameter_checker,
5762
ignore_pos_arg_names=ignore_pos_arg_names))
@@ -233,8 +238,7 @@ def visit_overloaded(self, left: Overloaded) -> bool:
233238
right = self.right
234239
if isinstance(right, Instance):
235240
return is_subtype(left.fallback, right)
236-
elif isinstance(right, CallableType) or is_named_instance(
237-
right, 'builtins.type'):
241+
elif isinstance(right, CallableType):
238242
for item in left.items():
239243
if is_subtype(item, right, self.check_type_parameter,
240244
ignore_pos_arg_names=self.ignore_pos_arg_names):
@@ -275,8 +279,7 @@ def visit_type_type(self, left: TypeType) -> bool:
275279
# This is unsound, we don't check the __init__ signature.
276280
return is_subtype(left.item, right.ret_type)
277281
if isinstance(right, Instance):
278-
if right.type.fullname() in ('builtins.type', 'builtins.object'):
279-
# Treat builtins.type the same as Type[Any];
282+
if right.type.fullname() == 'builtins.object':
280283
# treat builtins.object the same as Any.
281284
return True
282285
item = left.item

mypy/test/testsubtypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def test_var_arg_callable_subtyping_9(self) -> None:
168168
self.fx.callable_var_arg(0, self.fx.b, self.fx.d))
169169

170170
def test_type_callable_subtyping(self) -> None:
171-
self.assert_strict_subtype(
171+
self.assert_subtype(
172172
self.fx.callable_type(self.fx.d, self.fx.a), self.fx.type_type)
173173

174174
self.assert_strict_subtype(

test-data/unit/check-classes.test

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,43 @@ def foo(c: Type[C], d: Type[D]) -> None:
21652165
[out]
21662166
main:7: error: Revealed type is 'builtins.list[Type[__main__.B]]'
21672167

2168+
[case testTypeEquivalentTypeAny]
2169+
from typing import Type, Any
2170+
2171+
a = None # type: Type[Any]
2172+
b = a # type: type
2173+
2174+
x = None # type: type
2175+
y = x # type: Type[Any]
2176+
2177+
class C: ...
2178+
2179+
p = None # type: type
2180+
q = p # type: Type[C]
2181+
2182+
[builtins fixtures/list.pyi]
2183+
[out]
2184+
2185+
[case testTypeEquivalentTypeAny2]
2186+
from typing import Type, Any, TypeVar, Generic
2187+
2188+
class C: ...
2189+
x = None # type: type
2190+
y = None # type: Type[Any]
2191+
z = None # type: Type[C]
2192+
2193+
lst = [x, y, z]
2194+
reveal_type(lst) # E: Revealed type is 'builtins.list[builtins.type*]'
2195+
2196+
T1 = TypeVar('T1', bound=type)
2197+
T2 = TypeVar('T2', bound=Type[Any])
2198+
class C1(Generic[T1]): ...
2199+
class C2(Generic[T2]): ...
2200+
2201+
C1[Type[Any]], C2[type] # both these should not fail
2202+
[builtins fixtures/list.pyi]
2203+
[out]
2204+
21682205
[case testTypeMatchesOverloadedFunctions]
21692206
from typing import Type, overload, Union
21702207

0 commit comments

Comments
 (0)