diff --git a/changelog.d/20230905_090226_rra_DM_40638a.md b/changelog.d/20230905_090226_rra_DM_40638a.md new file mode 100644 index 00000000..5f36229d --- /dev/null +++ b/changelog.d/20230905_090226_rra_DM_40638a.md @@ -0,0 +1,3 @@ +### Bug fixes + +- Fix typing of the `safir.asyncio.run_with_asyncio` decorator so that it doesn't mask the type of the underlying function. diff --git a/src/safir/asyncio.py b/src/safir/asyncio.py index 8aba891b..6201b5c1 100644 --- a/src/safir/asyncio.py +++ b/src/safir/asyncio.py @@ -7,16 +7,24 @@ from datetime import timedelta from functools import wraps from types import EllipsisType -from typing import Any, Generic, TypeVar +from typing import Generic, ParamSpec, TypeVar from .datetime import current_datetime +#: Parameter spec for functions decorated by `run_with_asyncio`. +P = ParamSpec("P") + +#: Type variable for return type of decorated by `run_with_asyncio`. +F = TypeVar("F") + #: Type variable of objects being stored in `AsyncMultiQueue`. T = TypeVar("T") __all__ = [ "AsyncMultiQueue", "AsyncMultiQueueError", + "F", + "P", "run_with_asyncio", "T", ] @@ -187,8 +195,8 @@ def qsize(self) -> int: def run_with_asyncio( - f: Callable[..., Coroutine[Any, Any, T]] -) -> Callable[..., T]: + f: Callable[P, Coroutine[None, None, T]] +) -> Callable[P, T]: """Run the decorated function with `asyncio.run`. Intended to be used as a decorator around an async function that needs to @@ -230,7 +238,7 @@ async def init() -> None: """ @wraps(f) - def wrapper(*args: Any, **kwargs: Any) -> T: + def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: return asyncio.run(f(*args, **kwargs)) return wrapper