Skip to content

Commit 085b88f

Browse files
author
hauntsaninja
committed
Fix crash with overload and callable object decorators
Fixes the crash in #8356, as identified by @pranavrajpal Note that we still don't support the singledispatch in that issue, since we get 'overloaded function has no attribute "register"', but that's much easier to work around than a crash.
1 parent d7c4e69 commit 085b88f

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

mypy/checker.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,14 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None:
507507
# decorator or if the implementation is untyped -- we gave up on the types.
508508
inner_type = get_proper_type(inner_type)
509509
if inner_type is not None and not isinstance(inner_type, AnyType):
510-
assert isinstance(inner_type, CallableType)
511-
impl_type = inner_type
510+
if isinstance(inner_type, CallableType):
511+
impl_type = inner_type
512+
elif isinstance(inner_type, Instance):
513+
inner_call = find_member('__call__', inner_type, inner_type, is_operator=True)
514+
assert inner_call is not None
515+
impl_type = cast(CallableType, inner_call)
516+
else:
517+
assert False
512518

513519
is_descriptor_get = defn.info and defn.name == "__get__"
514520
for i, item in enumerate(defn.items):

test-data/unit/check-overloading.test

+44
Original file line numberDiff line numberDiff line change
@@ -5339,3 +5339,47 @@ def register(cls: Any) -> Any: return None
53395339
x = register(Foo)
53405340
reveal_type(x) # N: Revealed type is "builtins.int"
53415341
[builtins fixtures/dict.pyi]
5342+
5343+
5344+
[case testOverloadWithObjectDecorator]
5345+
from typing import Any, Callable, Union, overload
5346+
5347+
class A:
5348+
def __call__(self, *arg, **kwargs) -> None: ...
5349+
5350+
def dec_a(f: Callable[..., Any]) -> A:
5351+
return A()
5352+
5353+
@overload
5354+
def f_a(arg: int) -> None: ...
5355+
@overload
5356+
def f_a(arg: str) -> None: ...
5357+
@dec_a
5358+
def f_a(arg): ...
5359+
5360+
class B:
5361+
def __call__(self, arg: Union[int, str]) -> None: ...
5362+
5363+
def dec_b(f: Callable[..., Any]) -> B:
5364+
return B()
5365+
5366+
@overload
5367+
def f_b(arg: int) -> None: ...
5368+
@overload
5369+
def f_b(arg: str) -> None: ...
5370+
@dec_b
5371+
def f_b(arg): ...
5372+
5373+
class C:
5374+
def __call__(self, arg: int) -> None: ...
5375+
5376+
def dec_c(f: Callable[..., Any]) -> C:
5377+
return C()
5378+
5379+
@overload
5380+
def f_c(arg: int) -> None: ...
5381+
@overload
5382+
def f_c(arg: str) -> None: ...
5383+
@dec_c # E: Overloaded function implementation does not accept all possible arguments of signature 2
5384+
def f_c(arg): ...
5385+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)