Description
Bug Report
Defining a TypeGuard for callable to check if coroutine doesn't work when passed a generic callable with Concatenate.
To Reproduce
- Write this code
_PArgs = ParamSpec("_PArgs")
def iscoroutinefunc(func: Callable[_PArgs, Any]) -> TypeGuard[Callable[_PArgs, Coroutine[Any, Any, Any]]]:
return inspect.iscoroutinefunction(func)
- Call the type guard like this:
_PRouteParams = ParamSpec("_PRouteParams")
async def my_coro(x: int, y: int, z: int) -> str:
await asyncio.sleep(1)
return str(x + y + z)
async def execute_if_coro(
my_func_or_coro: Callable[Concatenate[int, _PRouteParams], Any], *args: _PRouteParams.args, **kwargs: _PRouteParams.kwargs
) -> None:
if iscoroutinefunc(my_func_or_coro):
await my_func_or_coro(3, *args, **kwargs)
else:
my_func_or_coro(3, *args, **kwargs)
await execute_if_coro(my_coro, 5, z=6)
- Run mypy on above code with "strict=True" setting
Expected Behavior
I expected mypy to infer in execute_if_coro
that my_func_or_coro
can receive an a positional integer before the additional *args and **kwargs and that the result will be awaitable using await
keyword.
Actual Behavior
Mypy reports 2 errors
- Argument 1 to "iscoroutinefunc" has incompatible type "Callable[[int, **_PRouteParams], Any]"; expected "Callable[[int, **_PRouteParams], Any]
- Argument 1 has incompatible type "int"; expected "[int, **_PRouteParams.args]"
Your Environment
- Mypy version used: 0.971
- Mypy command-line flags: N/A
- Mypy configuration options from
mypy.ini
(and other config files):
follow_imports = "normal"
ignore_errors = false
implicit_reexport = false
warn_redundant_casts = true
warn_unused_ignores = true
disallow_any_generics = true
disallow_untyped_defs = true
check_untyped_defs = true
allow_redefinition = false
local_partial_types = true
strict_optional = true
strict_equality = true
warn_unused_configs = true
warn_unreachable = true
warn_no_return = true
no_implicit_optional = true
strict = true
- Python version used: 3.10.4
- Operating system and version: Windows 11