-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
as designedNot a bug, working as intendedNot a bug, working as intended
Description
I am writing a decorator that caches the result of the decorated function. Should be a trivial use case. The decorator supports both regular function and async function. However, I don't seem to be able to find a way to add type annotations that can make Pyright happy.
My original code was like this:
import inspect
from collections.abc import Callable
from functools import wraps
from typing import TypeVar
from typing_extensions import ParamSpec
P = ParamSpec("P")
R = TypeVar("R")
def cache(func: Callable[P, R]) -> Callable[P, R]:
if inspect.iscoroutinefunction(func):
@wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
result = await func(*args, **kwargs)
# Omitted the code to add the result to cache
return result
else:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
result = func(*args, **kwargs)
# Ommitted the code to add the result to cache
return result
return wrapperPyright complained that the the type R is not awaitable, so I make some changes to comply:
import inspect
from collections.abc import Awaitable, Callable
from functools import wraps
from typing import TypeVar, Union
from typing_extensions import ParamSpec
P = ParamSpec("P")
R = TypeVar("R")
def cache(
func: Union[Callable[P, R], Callable[P, Awaitable[R]]]
) -> Union[Callable[P, R], Callable[P, Awaitable[R]]]:
if inspect.iscoroutinefunction(func):
@wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
result = await func(*args, **kwargs)
# Omitted the code to add the result to cache
return result
else:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
result = func(*args, **kwargs)
# Ommitted the code to add the result to cache
return result
return wrapperPyright still complained that the type R is not awaitable. It seems the problem originates from that Pyright didn't narrow the type of func after the inspect.iscoroutinefunction call?
I don't know how to fix the type annotations here. I find adding type annotations in situations involving higher order functions quite tricky.
gjoseph92
Metadata
Metadata
Assignees
Labels
as designedNot a bug, working as intendedNot a bug, working as intended