def test_alru_cache_origin(loop): asyncio.set_event_loop(loop) async def coro(): pass coro_wrapped = alru_cache(coro) assert coro_wrapped._origin is coro coro_wrapped = alru_cache(partial(coro)) assert coro_wrapped._origin is coro
async def __aenter__(self): if callable(self.http_session): self.http_session = self.http_session() self.http_session = await self.exit_stack.enter_async_context( self.http_session) self.get_json = alru_cache(self.get_json, loop=self.loop, cache_exceptions=False) return self
async def test_alru_cache_dict_not_shared(check_lru, loop): async def coro(val): return val coro1 = alru_cache()(coro) coro2 = alru_cache()(coro) ret1 = await coro1(1) check_lru(coro1, hits=0, misses=1, cache=1, tasks=0) ret2 = await coro2(1) check_lru(coro2, hits=0, misses=1, cache=1, tasks=0) assert ret1 == ret2 assert coro1._cache[1].result() == coro2._cache[1].result() assert coro1._cache != coro2._cache assert coro1._cache.keys() == coro2._cache.keys() assert coro1._cache is not coro2._cache
def test_alru_cache_fn_called(check_lru, loop): asyncio.set_event_loop(loop) async def coro(): pass coro_wrapped = alru_cache(coro) assert asyncio.iscoroutinefunction(coro_wrapped) for attr in alru_cache_attrs: assert hasattr(coro_wrapped, attr) for attr in alru_cache_calable_attrs: assert callable(getattr(coro_wrapped, attr)) assert isinstance(coro_wrapped._cache, dict) assert isinstance(coro_wrapped.tasks, set) check_lru(coro_wrapped, hits=0, misses=0, cache=0, tasks=0) assert asyncio.iscoroutine(coro_wrapped())
def simple_decorator(func): if inspect.iscoroutinefunction(func): return async_lru.alru_cache(maxsize=maxsize)(func) return functools.lru_cache(maxsize=maxsize)(func)
async def executor(self, executor_protocol: ExecutorProtocol, event_context, extra_parameter={}, lru_cache_sets=None ): lru_cache_sets = lru_cache_sets or {} executor_protocol: ExecutorProtocol for depend in executor_protocol.dependencies: if not inspect.isclass(depend.func): depend_func = depend.func elif hasattr(depend.func, "__call__"): depend_func = depend.func.__call__ else: raise TypeError("must be callable.") if depend_func in lru_cache_sets and depend.cache: depend_func = lru_cache_sets[depend_func] else: if depend.cache: original = depend_func if inspect.iscoroutinefunction(depend_func): depend_func = alru_cache(depend_func) else: depend_func = lru_cache(depend_func) lru_cache_sets[original] = depend_func result = await self.executor_with_middlewares( depend_func, depend.middlewares, event_context, lru_cache_sets ) if result is TRACEBACKED: return TRACEBACKED ParamSignatures = argument_signature(executor_protocol.callable) PlaceAnnotation = self.get_annotations_mapping() CallParams = {} for name, annotation, default in ParamSignatures: if default: if isinstance(default, Depend): if not inspect.isclass(default.func): depend_func = default.func elif hasattr(default.func, "__call__"): depend_func = default.func.__call__ else: raise TypeError("must be callable.") if depend_func in lru_cache_sets and default.cache: depend_func = lru_cache_sets[depend_func] else: if default.cache: original = depend_func if inspect.iscoroutinefunction(depend_func): depend_func = alru_cache(depend_func) else: depend_func = lru_cache(depend_func) lru_cache_sets[original] = depend_func CallParams[name] = await self.executor_with_middlewares( depend_func, default.middlewares, event_context, lru_cache_sets ) continue else: raise RuntimeError("checked a unexpected default value.") else: if annotation in PlaceAnnotation: CallParams[name] = PlaceAnnotation[annotation](event_context) continue else: if name not in extra_parameter: raise RuntimeError(f"checked a unexpected annotation: {annotation}") try: async with AsyncExitStack() as stack: sorted_middlewares = self.sort_middlewares(executor_protocol.middlewares) for async_middleware in sorted_middlewares['async']: await stack.enter_async_context(async_middleware) for normal_middleware in sorted_middlewares['normal']: stack.enter_context(normal_middleware) return await self.run_func(executor_protocol.callable, **CallParams, **extra_parameter) except exceptions.Cancelled: return TRACEBACKED except Exception as e: await self.put_exception(event_context, e) return TRACEBACKED
def test_alru_cache_not_callable(loop): with pytest.raises(NotImplementedError): alru_cache("foo")
from concurrent.futures import CancelledError from async_lru import alru_cache from studip_fuse.avfs.real_path import RealPath cache = alru_cache(cache_exceptions=False) __all__ = ["CachingRealPath"] def peek_cache(cached_func, *fn_args, **fn_kwargs): from functools import _make_key if getattr(cached_func, "__self__", None): fn_args = (cached_func.__self__, ) + fn_args key = _make_key(fn_args, fn_kwargs, False) return cached_func._cache.get(key) class CachingRealPath(RealPath.with_middleware(cache, cache), RealPath): async def getxattr(self): xattrs = await super(CachingRealPath, self).getxattr() if self.is_folder: fut = peek_cache(self.list_contents) if fut is not None: if fut.done(): try: exc = fut.exception() except CancelledError as e: exc = e if exc:
def __init__(self): self.coro = alru_cache(partial(self._coro, 2))
class Obj: async def _coro(self, val): return val coro = alru_cache(partialmethod(_coro, 2))
import logging from typing import Dict from async_lru import alru_cache from asyncpg.pool import Pool, create_pool from marshmallow import Schema, fields, post_load from .exceptions import CompanyNotFound from .models import Company, CompanySelection __all__ = ( "DB", "DBSchema", ) CACHED = alru_cache(maxsize=512, cache_exceptions=False) class DB: __slots__ = ("_pool", "_logger") def __init__(self, pool: Pool, logger: logging.Logger): self._pool = pool self._logger = logger async def setup(self) -> None: await self._pool async def cleanup(self) -> None: await self._pool.close()