From 8d69e8d6aa443fee42757de49dc9643b96257797 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Sat, 5 Jul 2025 17:54:50 -0500 Subject: [PATCH 1/5] a mypy fixes and a few optimizations --- async_lru/__init__.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/async_lru/__init__.py b/async_lru/__init__.py index ecca5fdd..65e423a1 100644 --- a/async_lru/__init__.py +++ b/async_lru/__init__.py @@ -17,6 +17,7 @@ Union, final, overload, + Any ) @@ -64,6 +65,7 @@ def cancel(self) -> None: @final class _LRUCacheWrapper(Generic[_P, _R]): + def __init__( self, fn: Callable[_P, Coroutine[object, object, _R]], @@ -108,7 +110,7 @@ def __init__( self.__misses = 0 self.__tasks: Set["asyncio.Task[_R]"] = set() - def cache_invalidate(self, /, *args: _P.args, **kwargs: _P.kwargs) -> bool: + def cache_invalidate(self, /, *args:_P.args, **kwargs:_P.kwargs) -> bool: key = _make_key(args, kwargs, self.__typed) cache_item = self.__cache.pop(key, None) @@ -208,32 +210,32 @@ async def __call__(self, /, *fn_args: _P.args, **fn_kwargs: _P.kwargs) -> _R: return cache_item.fut.result() fut = loop.create_future() - coro = self.__wrapped__(*fn_args, **fn_kwargs) - task = loop.create_task(coro) + task = loop.create_task( + self.__wrapped__(*fn_args, **fn_kwargs) + ) self.__tasks.add(task) task.add_done_callback(partial(self._task_done_callback, fut, key)) self.__cache[key] = _CacheItem(fut, None) if self.__maxsize is not None and len(self.__cache) > self.__maxsize: - dropped_key, cache_item = self.__cache.popitem(last=False) - cache_item.cancel() + self.__cache.popitem(last=False)[1].cancel() self._cache_miss(key) return await asyncio.shield(fut) @overload - def __get__(self, instance: _T, owner: None) -> Self: + def __get__(self, instance: Any, owner: None) -> Self: ... @overload def __get__( - self, instance: _T, owner: Type[_T] + self, instance: _T, owner: Type[Any] ) -> "_LRUCacheWrapperInstanceMethod[_P, _R, _T]": ... def __get__( - self, instance: _T, owner: Optional[Type[_T]] + self, instance: Any, owner: Optional[Type[Any]] ) -> Union[Self, "_LRUCacheWrapperInstanceMethod[_P, _R, _T]"]: if owner is None: return self @@ -280,7 +282,7 @@ def __init__( self.__wrapper = wrapper def cache_invalidate(self, /, *args: _P.args, **kwargs: _P.kwargs) -> bool: - return self.__wrapper.cache_invalidate(self.__instance, *args, **kwargs) + return self.__wrapper.cache_invalidate(self.__instance, *args, **kwargs) # type: ignore[arg-type] def cache_clear(self) -> None: self.__wrapper.cache_clear() From e121d01dd977905dc9d3c250c0a677f422abaf31 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Sat, 5 Jul 2025 23:11:43 -0500 Subject: [PATCH 2/5] ran pre-commit locally and made some extra fixes --- async_lru/__init__.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/async_lru/__init__.py b/async_lru/__init__.py index 65e423a1..b28a9208 100644 --- a/async_lru/__init__.py +++ b/async_lru/__init__.py @@ -4,6 +4,7 @@ from asyncio.coroutines import _is_coroutine # type: ignore[attr-defined] from functools import _CacheInfo, _make_key, partial, partialmethod from typing import ( + Any, Callable, Coroutine, Generic, @@ -17,7 +18,6 @@ Union, final, overload, - Any ) @@ -65,7 +65,6 @@ def cancel(self) -> None: @final class _LRUCacheWrapper(Generic[_P, _R]): - def __init__( self, fn: Callable[_P, Coroutine[object, object, _R]], @@ -110,7 +109,7 @@ def __init__( self.__misses = 0 self.__tasks: Set["asyncio.Task[_R]"] = set() - def cache_invalidate(self, /, *args:_P.args, **kwargs:_P.kwargs) -> bool: + def cache_invalidate(self, /, *args: _P.args, **kwargs: _P.kwargs) -> bool: key = _make_key(args, kwargs, self.__typed) cache_item = self.__cache.pop(key, None) @@ -210,9 +209,7 @@ async def __call__(self, /, *fn_args: _P.args, **fn_kwargs: _P.kwargs) -> _R: return cache_item.fut.result() fut = loop.create_future() - task = loop.create_task( - self.__wrapped__(*fn_args, **fn_kwargs) - ) + task = loop.create_task(self.__wrapped__(*fn_args, **fn_kwargs)) self.__tasks.add(task) task.add_done_callback(partial(self._task_done_callback, fut, key)) @@ -282,7 +279,7 @@ def __init__( self.__wrapper = wrapper def cache_invalidate(self, /, *args: _P.args, **kwargs: _P.kwargs) -> bool: - return self.__wrapper.cache_invalidate(self.__instance, *args, **kwargs) # type: ignore[arg-type] + return self.__wrapper.cache_invalidate(self.__instance, *args, **kwargs) # type: ignore[arg-type] def cache_clear(self) -> None: self.__wrapper.cache_clear() @@ -298,8 +295,8 @@ def cache_info(self) -> _CacheInfo: def cache_parameters(self) -> _CacheParameters: return self.__wrapper.cache_parameters() - async def __call__(self, /, *fn_args: _P.args, **fn_kwargs: _P.kwargs) -> _R: - return await self.__wrapper(self.__instance, *fn_args, **fn_kwargs) # type: ignore[arg-type] + async def __call__(self, /, *args: _P.args, **kwargs: _P.kwargs) -> _R: + return self.__wrapper.cache_invalidate(self.__instance, *args, **kwargs) # type: ignore[arg-type] def _make_wrapper( From 85412735052e146c96f23a8874097e1aeeda4b87 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 11 Jul 2025 17:35:00 -0500 Subject: [PATCH 3/5] revert changes --- async_lru/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/async_lru/__init__.py b/async_lru/__init__.py index b28a9208..cf122fe6 100644 --- a/async_lru/__init__.py +++ b/async_lru/__init__.py @@ -216,7 +216,8 @@ async def __call__(self, /, *fn_args: _P.args, **fn_kwargs: _P.kwargs) -> _R: self.__cache[key] = _CacheItem(fut, None) if self.__maxsize is not None and len(self.__cache) > self.__maxsize: - self.__cache.popitem(last=False)[1].cancel() + dropped_key, cache_item = self.__cache.popitem(last=False) + cache_item.cancel() self._cache_miss(key) return await asyncio.shield(fut) @@ -227,12 +228,12 @@ def __get__(self, instance: Any, owner: None) -> Self: @overload def __get__( - self, instance: _T, owner: Type[Any] + self, instance: _T, owner: Type[_T] ) -> "_LRUCacheWrapperInstanceMethod[_P, _R, _T]": ... def __get__( - self, instance: Any, owner: Optional[Type[Any]] + self, instance: _T, owner: Optional[Type[_T]] ) -> Union[Self, "_LRUCacheWrapperInstanceMethod[_P, _R, _T]"]: if owner is None: return self From d97394431281ef9f1b36daa3fc99787f3ac3c298 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 11 Jul 2025 17:35:56 -0500 Subject: [PATCH 4/5] revert changes again --- async_lru/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async_lru/__init__.py b/async_lru/__init__.py index cf122fe6..d63bc174 100644 --- a/async_lru/__init__.py +++ b/async_lru/__init__.py @@ -223,7 +223,7 @@ async def __call__(self, /, *fn_args: _P.args, **fn_kwargs: _P.kwargs) -> _R: return await asyncio.shield(fut) @overload - def __get__(self, instance: Any, owner: None) -> Self: + def __get__(self, instance: _T, owner: None) -> Self: ... @overload From 31bef47af88c3089ae7ea9fbedf6e33d73f2dbd7 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 11 Jul 2025 17:41:11 -0500 Subject: [PATCH 5/5] some catching up with #508 --- async_lru/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/async_lru/__init__.py b/async_lru/__init__.py index d63bc174..6da57efb 100644 --- a/async_lru/__init__.py +++ b/async_lru/__init__.py @@ -320,7 +320,10 @@ def wrapper( if hasattr(fn, "_make_unbound_method"): fn = fn._make_unbound_method() - return _LRUCacheWrapper(fn, maxsize, typed, ttl) + wrapper = _LRUCacheWrapper(fn, maxsize, typed, ttl) + if sys.version_info >= (3, 12): + wrapper = inspect.markcoroutinefunction(wrapper) + return wrapper return wrapper