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

59 statements  

1"""Function decorator helpers. 

2 

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. 

6 

7""" 

8 

9# pyright: reportArgumentType=false, reportAttributeAccessIssue=false 

10 

11__all__ = () 

12 

13import functools 

14import types 

15 

16from ._decorator import ( 

17 _BasicMixin, 

18 _ConditionInfoMixin, 

19 _ConditionMixin, 

20 _InfoMixin, 

21 _LockedInfoMixin, 

22 _LockedMixin, 

23) 

24 

25 

26class _WrapperBase: 

27 """Wrapper base class providing the public cache attributes.""" 

28 

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 

37 

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) 

41 

42 def __reduce__(self): 

43 return self.__qualname__ 

44 

45 def __repr__(self): 

46 return f"<cached {self.__wrapped__!r}>" 

47 

48 

49class _BasicWrapper(_WrapperBase, _BasicMixin): 

50 def __init__(self, func, cache, key): 

51 _WrapperBase.__init__(self, func, cache, key) 

52 _BasicMixin.__init__(self, func) 

53 

54 

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) 

59 

60 

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) 

65 

66 

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) 

71 

72 

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) 

77 

78 

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) 

83 

84 

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