11from collections .abc import Awaitable , Callable , Generator
2- from typing import NewType , TypeVar , cast , final
2+ from functools import wraps
3+ from typing import NewType , ParamSpec , TypeVar , cast , final
34
45_ValueType = TypeVar ('_ValueType' )
5- _FunctionCoroType = TypeVar ('_FunctionCoroType' , bound = Callable [..., Awaitable ])
6+ _AwaitableT = TypeVar ('_AwaitableT' , bound = Awaitable )
7+ _Ps = ParamSpec ('_Ps' )
68
79_Sentinel = NewType ('_Sentinel' , object )
810_sentinel : _Sentinel = cast (_Sentinel , object ())
@@ -104,7 +106,9 @@ async def _awaitable(self) -> _ValueType:
104106 return self ._cache # type: ignore
105107
106108
107- def reawaitable (coro : _FunctionCoroType ) -> _FunctionCoroType :
109+ def reawaitable (
110+ coro : Callable [_Ps , _AwaitableT ],
111+ ) -> Callable [_Ps , _AwaitableT ]:
108112 """
109113 Allows to decorate coroutine functions to be awaitable multiple times.
110114
@@ -124,6 +128,12 @@ def reawaitable(coro: _FunctionCoroType) -> _FunctionCoroType:
124128 >>> assert anyio.run(main) == 3
125129
126130 """
127- return lambda * args , ** kwargs : ReAwaitable ( # type: ignore
128- coro (* args , ** kwargs ),
129- )
131+
132+ @wraps (coro )
133+ def decorator (
134+ * args : _Ps .args ,
135+ ** kwargs : _Ps .kwargs ,
136+ ) -> _AwaitableT :
137+ return ReAwaitable (coro (* args , ** kwargs )) # type: ignore[return-value]
138+
139+ return decorator
0 commit comments