Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cachetools/_cached.py: 81%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Function decorator helpers.
3At least for now, the implementation prefers clarity and performance
4over ease of maintenance, thus providing separate wrappers for all
5valid combinations of parameters lock, condition and info.
7"""
9# pyright: reportArgumentType=false, reportAttributeAccessIssue=false
11__all__ = ()
13import functools
14import types
16from ._decorator import (
17 _BasicMixin,
18 _ConditionInfoMixin,
19 _ConditionMixin,
20 _InfoMixin,
21 _LockedInfoMixin,
22 _LockedMixin,
23)
26class _WrapperBase:
27 """Wrapper base class providing the public cache attributes."""
29 def __init__(self, func, cache, key, lock=None, cond=None):
30 # update first, so func.__dict__ cannot override wrapper state,
31 # e.g. when stacking decorators
32 functools.update_wrapper(self, func)
33 self.cache = cache
34 self.cache_key = key
35 self.cache_lock = lock
36 self.cache_condition = cond
38 # descriptor and pickle support as for functools.lru_cache (C version)
39 def __get__(self, obj, objtype=None):
40 return self if obj is None else types.MethodType(self, obj)
42 def __reduce__(self):
43 return self.__qualname__
45 def __repr__(self):
46 return f"<cached {self.__wrapped__!r}>"
49class _BasicWrapper(_WrapperBase, _BasicMixin):
50 def __init__(self, func, cache, key):
51 _WrapperBase.__init__(self, func, cache, key)
52 _BasicMixin.__init__(self, func)
55class _LockedWrapper(_WrapperBase, _LockedMixin):
56 def __init__(self, func, cache, key, lock):
57 _WrapperBase.__init__(self, func, cache, key, lock)
58 _LockedMixin.__init__(self, func)
61class _ConditionWrapper(_WrapperBase, _ConditionMixin):
62 def __init__(self, func, cache, key, lock, cond):
63 _WrapperBase.__init__(self, func, cache, key, lock, cond)
64 _ConditionMixin.__init__(self, func)
67class _InfoWrapper(_WrapperBase, _InfoMixin):
68 def __init__(self, func, cache, key, info):
69 _WrapperBase.__init__(self, func, cache, key)
70 _InfoMixin.__init__(self, func, info)
73class _LockedInfoWrapper(_WrapperBase, _LockedInfoMixin):
74 def __init__(self, func, cache, key, lock, info):
75 _WrapperBase.__init__(self, func, cache, key, lock)
76 _LockedInfoMixin.__init__(self, func, info)
79class _ConditionInfoWrapper(_WrapperBase, _ConditionInfoMixin):
80 def __init__(self, func, cache, key, lock, cond, info):
81 _WrapperBase.__init__(self, func, cache, key, lock, cond)
82 _ConditionInfoMixin.__init__(self, func, info)
85def _wrapper(func, cache, key, lock=None, cond=None, info=None):
86 if info is not None:
87 if cond is not None and lock is not None:
88 wrapper = _ConditionInfoWrapper(func, cache, key, lock, cond, info)
89 elif cond is not None:
90 wrapper = _ConditionInfoWrapper(func, cache, key, cond, cond, info)
91 elif lock is not None:
92 wrapper = _LockedInfoWrapper(func, cache, key, lock, info)
93 else:
94 wrapper = _InfoWrapper(func, cache, key, info)
95 else:
96 if cond is not None and lock is not None:
97 wrapper = _ConditionWrapper(func, cache, key, lock, cond)
98 elif cond is not None:
99 wrapper = _ConditionWrapper(func, cache, key, cond, cond)
100 elif lock is not None:
101 wrapper = _LockedWrapper(func, cache, key, lock)
102 else:
103 wrapper = _BasicWrapper(func, cache, key)
104 return wrapper