diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 71b8b0ba59f5..84fda7955d75 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -1091,6 +1091,11 @@ def visit_type_type(self, left: TypeType) -> bool: right = self.right if isinstance(right, TypeType): return self._is_subtype(left.item, right.item) + if isinstance(right, Overloaded) and right.is_type_obj(): + # Same as in other direction: if it's a constructor callable, all + # items should belong to the same class' constructor, so it's enough + # to check one of them. + return self._is_subtype(left, right.items[0]) if isinstance(right, CallableType): if self.proper_subtype and not right.is_type_obj(): # We can't accept `Type[X]` as a *proper* subtype of Callable[P, X] diff --git a/test-data/unit/check-assert-type-fail.test b/test-data/unit/check-assert-type-fail.test index 89b3a863f8c7..514650649641 100644 --- a/test-data/unit/check-assert-type-fail.test +++ b/test-data/unit/check-assert-type-fail.test @@ -31,3 +31,19 @@ def f(si: arr.array[int]): from typing import assert_type, Callable def myfunc(arg: int) -> None: pass assert_type(myfunc, Callable[[int], None]) # E: Expression is of type "Callable[[Arg(int, 'arg')], None]", not "Callable[[int], None]" + +[case testAssertTypeOverload] +from typing import assert_type, overload + +class Foo: + @overload + def __new__(cls, x: int) -> Foo: ... + @overload + def __new__(cls, x: str) -> Foo: ... + def __new__(cls, x: "int | str") -> Foo: + return cls(0) + +assert_type(Foo, type[Foo]) +A = Foo +assert_type(A, type[Foo]) +[builtins fixtures/tuple.pyi]