Skip to content

Commit 1aabd22

Browse files
ilevkivskyigvanrossum
authored andcommitted
Fix overloading on Type[...] (#4037)
Fixes #4027 Currently overloads on `Type[...]` don't accept class objects whose `__init__` is itself overloaded. I fix this by simply allowing `FunctionLike` with `.is_type_obj()` returning `True` instead of only `Callable`.
1 parent 5ca89e5 commit 1aabd22

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

mypy/checkexpr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,10 +2817,10 @@ def overload_arg_similarity(actual: Type, formal: Type) -> int:
28172817
# Since Type[T] is covariant, check if actual = Type[A] is
28182818
# a subtype of formal = Type[F].
28192819
return overload_arg_similarity(actual.item, formal.item)
2820-
elif isinstance(actual, CallableType) and actual.is_type_obj():
2820+
elif isinstance(actual, FunctionLike) and actual.is_type_obj():
28212821
# Check if the actual is a constructor of some sort.
28222822
# Note that this is this unsound, since we don't check the __init__ signature.
2823-
return overload_arg_similarity(actual.ret_type, formal.item)
2823+
return overload_arg_similarity(actual.items()[0].ret_type, formal.item)
28242824
else:
28252825
return 0
28262826
if isinstance(actual, TypedDictType):

test-data/unit/check-overloading.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,3 +1272,28 @@ a: Any
12721272
# The return type is not ambiguous so Any arguments cause no ambiguity.
12731273
reveal_type(f(a, 1, 1)) # E: Revealed type is 'builtins.str'
12741274
reveal_type(f(1, *a)) # E: Revealed type is 'builtins.str'
1275+
1276+
[case testOverloadOnOverloadWithType]
1277+
from typing import Any, Type, TypeVar, overload
1278+
from mod import MyInt
1279+
T = TypeVar('T')
1280+
1281+
@overload
1282+
def make(cls: Type[T]) -> T: pass
1283+
@overload
1284+
def make() -> Any: pass
1285+
1286+
def make(*args):
1287+
pass
1288+
1289+
c = make(MyInt)
1290+
reveal_type(c) # E: Revealed type is 'mod.MyInt*'
1291+
1292+
[file mod.pyi]
1293+
from typing import overload
1294+
class MyInt:
1295+
@overload
1296+
def __init__(self, x: str) -> None: pass
1297+
@overload
1298+
def __init__(self, x: str, y: int) -> None: pass
1299+
[out]

0 commit comments

Comments
 (0)