Skip to content

Commit 653610f

Browse files
authored
Narrow Callable generic return types (#20868)
Requires #20864 to be merged to work Fixes #20628
1 parent 55401f2 commit 653610f

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

mypy/meet.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,15 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
229229
):
230230
return original_declared
231231
return meet_types(original_declared, original_narrowed)
232+
elif (
233+
isinstance(declared, CallableType)
234+
and isinstance(narrowed, CallableType)
235+
and has_type_vars(declared.ret_type)
236+
):
237+
return narrowed.copy_modified(
238+
ret_type=narrow_declared_type(declared.ret_type, narrowed.ret_type)
239+
)
240+
232241
return original_narrowed
233242

234243

test-data/unit/check-narrowing.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,3 +3912,26 @@ def get_owner(uid: UserId, tid: TeamId):
39123912
reveal_type(INVALID) # N: Revealed type is "builtins.int"
39133913
return None
39143914
[builtins fixtures/primitives.pyi]
3915+
3916+
[case testNarrowCallableTypeVarByEquality]
3917+
from typing import Callable, TypeVar
3918+
3919+
T = TypeVar("T")
3920+
3921+
def remove(path: str) -> None: ...
3922+
def unlink(path: str) -> None: ...
3923+
3924+
def f1(func: Callable[..., T], arg: str) -> T:
3925+
if func == remove:
3926+
reveal_type(func) # N: Revealed type is "def (path: builtins.str) -> T`-1"
3927+
reveal_type(func(arg)) # N: Revealed type is "T`-1"
3928+
return func(arg)
3929+
return func(arg)
3930+
3931+
def f2(func: Callable[..., T], arg: str) -> T:
3932+
if func in [unlink, remove]:
3933+
reveal_type(func) # N: Revealed type is "def (path: builtins.str) -> T`-1"
3934+
reveal_type(func(arg)) # N: Revealed type is "T`-1"
3935+
return func(arg)
3936+
return func(arg)
3937+
[builtins fixtures/primitives.pyi]

0 commit comments

Comments
 (0)