1515from __future__ import annotations
1616
1717import asyncio
18- from collections .abc import Callable , Coroutine , Hashable
18+ from collections .abc import Awaitable , Callable , Coroutine , Hashable
1919from functools import partial , wraps
2020from typing import Any , ParamSpec , TypeVar
2121
2626
2727P = ParamSpec ("P" )
2828T = TypeVar ("T" )
29- K = TypeVar ("K" )
30- V = TypeVar ("V" )
3129
3230
3331type CoroFunc [** P , T ] = Callable [P , Coroutine [Any , Any , T ]]
32+ type CoroLike [** P , T ] = Callable [P , Awaitable [T ]]
3433
3534
3635class LRU [K , V ]:
@@ -59,7 +58,7 @@ def remove(self, key: K) -> None:
5958
6059def corocache (
6160 ttl : float | None = None ,
62- ) -> Callable [[CoroFunc [P , T ]], CoroFunc [P , T ]]:
61+ ) -> Callable [[CoroLike [P , T ]], CoroFunc [P , T ]]:
6362 """Decorator to cache coroutine functions.
6463
6564 This is less powerful than the version in task_cache.py but may work better for
@@ -71,37 +70,37 @@ def corocache(
7170
7271 The ordering of args and kwargs matters."""
7372
74- def wrapper (coro : CoroFunc [P , T ]) -> CoroFunc [P , T ]:
75- internal_cache : dict [Hashable , asyncio .Task [T ]] = {}
73+ def wrapper (coro : CoroLike [P , T ]) -> CoroFunc [P , T ]:
74+ internal_cache : dict [Hashable , asyncio .Future [T ]] = {}
7675
7776 async def wrapped (* args : P .args , ** kwargs : P .kwargs ) -> T :
7877 key = make_key (args , kwargs )
7978 try :
8079 return await internal_cache [key ]
8180 except KeyError :
82- internal_cache [key ] = task = asyncio .create_task (coro (* args , ** kwargs ))
81+ internal_cache [key ] = fut = asyncio .ensure_future (coro (* args , ** kwargs ))
8382 if ttl is not None :
84- # This results in internal_cache.pop(key, task ) later
83+ # This results in internal_cache.pop(key, fut ) later
8584 # while avoiding a late binding issue with a lambda instead
8685 call_after_ttl = partial (
8786 asyncio .get_running_loop ().call_later ,
8887 ttl ,
8988 internal_cache .pop ,
9089 key ,
9190 )
92- task .add_done_callback (call_after_ttl )
93- return await task
91+ fut .add_done_callback (call_after_ttl )
92+ return await fut
9493
9594 return wrapped
9695
9796 return wrapper
9897
9998
100- def _lru_evict (ttl : float , cache : LRU [Hashable , Any ], key : Hashable , _ignored_task : object ) -> None :
99+ def _lru_evict (ttl : float , cache : LRU [Hashable , Any ], key : Hashable , _ignored_fut : object ) -> None :
101100 asyncio .get_running_loop ().call_later (ttl , cache .remove , key )
102101
103102
104- def lrucorocache (ttl : float | None = None , maxsize : int = 1024 ) -> Callable [[CoroFunc [P , T ]], CoroFunc [P , T ]]:
103+ def lrucorocache (ttl : float | None = None , maxsize : int = 1024 ) -> Callable [[CoroLike [P , T ]], CoroFunc [P , T ]]:
105104 """Decorator to cache coroutine functions.
106105
107106 This is less powerful than the version in task_cache.py but may work better for
@@ -113,22 +112,22 @@ def lrucorocache(ttl: float | None = None, maxsize: int = 1024) -> Callable[[Cor
113112
114113 The ordering of args and kwargs matters.
115114
116- tasks are evicted by LRU and ttl.
115+ futs are evicted by LRU and ttl.
117116 """
118117
119- def wrapper (coro : CoroFunc [P , T ]) -> CoroFunc [P , T ]:
120- internal_cache : LRU [Hashable , asyncio .Task [T ]] = LRU (maxsize )
118+ def wrapper (coro : CoroLike [P , T ]) -> CoroFunc [P , T ]:
119+ internal_cache : LRU [Hashable , asyncio .Future [T ]] = LRU (maxsize )
121120
122121 @wraps (coro )
123122 async def wrapped (* args : P .args , ** kwargs : P .kwargs ) -> T :
124123 key = make_key (args , kwargs )
125124 try :
126125 return await internal_cache [key ]
127126 except KeyError :
128- internal_cache [key ] = task = asyncio .create_task (coro (* args , ** kwargs ))
127+ internal_cache [key ] = fut = asyncio .ensure_future (coro (* args , ** kwargs ))
129128 if ttl is not None :
130- task .add_done_callback (partial (_lru_evict , ttl , internal_cache , key ))
131- return await task
129+ fut .add_done_callback (partial (_lru_evict , ttl , internal_cache , key ))
130+ return await fut
132131
133132 return wrapped
134133
0 commit comments