1616
1717import asyncio
1818import concurrent .futures as cf
19- from collections .abc import Callable , Hashable
19+ from collections .abc import Callable , Coroutine , Hashable
2020from functools import partial , wraps
2121
22- from . import _internal_types as i_types
2322from . import _typings as t
2423from ._paramkey import make_key
2524from .lru import LRU
2625
2726__all__ = ("lrutaskcache" , "taskcache" )
2827
28+ type CoroFunc [** P , R ] = Callable [P , Coroutine [t .Any , t .Any , R ]]
29+ type TaskFunc [** P , R ] = Callable [P , asyncio .Task [R ]]
30+ type TaskCoroFunc [** P , R ] = CoroFunc [P , R ] | TaskFunc [P , R ]
31+
32+ #: Note CacheTransformers recieve a tuple (args) and dict(kwargs)
33+ #: rather than a ParamSpec of the decorated function.
34+ #: Warning: Mutations will impact callsite, return new objects as needed.
35+ type CacheTransformer = Callable [
36+ [tuple [t .Any , ...], dict [str , t .Any ]], tuple [tuple [t .Any , ...], dict [str , t .Any ]]
37+ ]
38+
39+
40+ class TaskCacheDeco (t .Protocol ):
41+ def __call__ [** P , R ](self , c : TaskCoroFunc [P , R ], / ) -> TaskFunc [P , R ]: ...
42+
2943
3044# Non-annotation assignments for transformed functions
3145_WRAP_ASSIGN = ("__module__" , "__name__" , "__qualname__" , "__doc__" )
@@ -44,7 +58,7 @@ class _WrappedSignature[**P, R]:
4458 #: PYUPGRADE: Ensure inspect.signature still accepts this
4559 # as func.__signature__
4660 # Known working: py 3.12.0 - py3.14a6 range inclusive
47- def __init__ (self , f : i_types . TaskCoroFunc [P , R ], w : i_types . TaskFunc [P , R ]) -> None :
61+ def __init__ (self , f : TaskCoroFunc [P , R ], w : TaskFunc [P , R ]) -> None :
4862 self ._f : Callable [..., t .Any ] = f # anotation needed for inspect use below....
4963 self ._w = w
5064 self ._sig : t .Any | None = None
@@ -92,8 +106,8 @@ async def _await[R](fut: asyncio.Future[R]) -> R:
92106def taskcache (
93107 ttl : float | None = None ,
94108 * ,
95- cache_transform : i_types . CacheTransformer | None = None ,
96- ) -> i_types . TaskCacheDeco :
109+ cache_transform : CacheTransformer | None = None ,
110+ ) -> TaskCacheDeco :
97111 """Cache the results of the decorated coroutine.
98112
99113 Decorator to modify coroutine functions to instead act as functions
@@ -132,7 +146,7 @@ def taskcache(
132146 def key_func (args : tuple [t .Any , ...], kwds : dict [t .Any , t .Any ], / ) -> Hashable :
133147 return make_key (* cache_transform (args , kwds ))
134148
135- def wrapper [** P , R ](coro : i_types . TaskCoroFunc [P , R ], / ) -> i_types . TaskFunc [P , R ]:
149+ def wrapper [** P , R ](coro : TaskCoroFunc [P , R ], / ) -> TaskFunc [P , R ]:
136150 internal_cache : dict [Hashable , cf .Future [R ]] = {}
137151
138152 def _internal_cache_evict (key : Hashable , _ignored_task : object ) -> None :
@@ -171,8 +185,8 @@ def lrutaskcache(
171185 ttl : float | None = None ,
172186 maxsize : int = 1024 ,
173187 * ,
174- cache_transform : i_types . CacheTransformer | None = None ,
175- ) -> i_types . TaskCacheDeco :
188+ cache_transform : CacheTransformer | None = None ,
189+ ) -> TaskCacheDeco :
176190 """Cache the results of the decorated coroutine.
177191
178192 Decorator to modify coroutine functions to instead act as functions
@@ -218,7 +232,7 @@ def lrutaskcache(
218232 def key_func (args : tuple [t .Any , ...], kwds : dict [t .Any , t .Any ], / ) -> Hashable :
219233 return make_key (* cache_transform (args , kwds ))
220234
221- def wrapper [** P , R ](coro : i_types . TaskCoroFunc [P , R ], / ) -> i_types . TaskFunc [P , R ]:
235+ def wrapper [** P , R ](coro : TaskCoroFunc [P , R ], / ) -> TaskFunc [P , R ]:
222236 internal_cache : LRU [Hashable , cf .Future [R ]] = LRU (maxsize )
223237
224238 def _internal_cache_evict (key : Hashable , _ignored_task : object ) -> None :
0 commit comments