11import asyncio
2- import functools
32from collections import OrderedDict
43from collections .abc import AsyncGenerator , Awaitable
54from contextlib import asynccontextmanager
5+ from functools import wraps
66
77from aiojobs import Scheduler
88
@@ -20,17 +20,17 @@ async def get_scheduler() -> AsyncGenerator[Scheduler, None]:
2020 yield scheduler
2121
2222
23- def async_lru_cache (maxsize : int = 128 ):
23+ def lru_acache (maxsize : int = 128 ):
2424 """
25- Caches a function's return value each time it is called.
25+ Caches an async function's return value each time it is called.
2626
2727 If the maxsize is reached, the least recently used value is removed.
2828 """
2929
3030 def decorator (func ):
3131 cache : OrderedDict [tuple , Awaitable ] = OrderedDict ()
3232
33- @functools . wraps (func )
33+ @wraps (func )
3434 async def wrapper (* args , ** kwargs ) -> Awaitable :
3535 # Create a cache key from event loop, args and kwargs, using frozenset for kwargs to ensure hashability
3636 key = (
@@ -49,6 +49,46 @@ async def wrapper(*args, **kwargs) -> Awaitable:
4949 cache [key ] = value
5050 cache .move_to_end (key )
5151
52+ # Remove the least recently used key if the cache is full
53+ if len (cache ) > maxsize :
54+ cache .popitem (last = False )
55+
56+ return value
57+
58+ return wrapper
59+
60+ return decorator
61+
62+
63+ def lru_cache (maxsize : int = 128 ):
64+ """
65+ Caches a sync function's return value each time it is called.
66+
67+ If the maxsize is reached, the least recently used value is removed.
68+ """
69+
70+ def decorator (func ):
71+ cache : OrderedDict [tuple , Awaitable ] = OrderedDict ()
72+
73+ @wraps (func )
74+ def wrapper (* args , ** kwargs ) -> Awaitable :
75+ # Create a cache key from args and kwargs, using frozenset for kwargs to ensure hashability
76+ key = (
77+ args ,
78+ frozenset (kwargs .items ()),
79+ )
80+
81+ if key in cache :
82+ # Move the recently accessed key to the end (most recently used)
83+ cache .move_to_end (key )
84+ return cache [key ]
85+
86+ # Compute the value since it's not cached
87+ value = func (* args , ** kwargs )
88+ cache [key ] = value
89+ cache .move_to_end (key )
90+
91+ # Remove the least recently used key if the cache is full
5292 if len (cache ) > maxsize :
5393 cache .popitem (last = False )
5494
0 commit comments