23
23
T_TTL = t .Union [int , float ]
24
24
T_FILTER = t .Union [str , t .List [t .Hashable ], t .Pattern , t .Callable ]
25
25
26
+
26
27
UNSET = object ()
27
28
28
29
@@ -46,6 +47,21 @@ class RemovalCause(Enum):
46
47
POPITEM = auto ()
47
48
48
49
50
+ #: Callback that will be executed when a cache entry is retrieved.
51
+
52
+ #: It is called with arguments ``(key, value, exists)`` where `key` is the cache key,
53
+ #: `value` is the value retrieved (could be the default),
54
+ #: and `exists` is whether the cache key exists or not.
55
+ T_ON_GET_CALLBACK = t .Optional [t .Callable [[t .Hashable , t .Any , bool ], None ]]
56
+
57
+ #: Callback that will be executed when a cache entry is removed.
58
+
59
+ #: It is called with arguments ``(key, value, cause)`` where `key` is the cache key,
60
+ #: `value` is the cached value at the time of deletion,
61
+ #: and `cause` is the reason the key was removed (see :class:`RemovalCause` for enumerated causes).
62
+ T_ON_DELETE_CALLBACK = t .Optional [t .Callable [[t .Hashable , t .Any , RemovalCause ], None ]]
63
+
64
+
49
65
class Cache :
50
66
"""
51
67
An in-memory, FIFO cache object.
@@ -74,7 +90,10 @@ class Cache:
74
90
default: Default value or function to use in :meth:`get` when key is not found. If callable,
75
91
it will be passed a single argument, ``key``, and its return value will be set for that
76
92
cache key.
93
+ on_get: Callback which will be executed when a cache entry is retrieved.
94
+ See :class:`T_ON_GET_CALLBACK` for details.
77
95
on_delete: Callback which will be executed when a cache entry is removed.
96
+ See :class:`T_ON_DELETE_CALLBACK` for details.
78
97
stats: Cache statistics.
79
98
"""
80
99
@@ -90,12 +109,14 @@ def __init__(
90
109
timer : t .Callable [[], T_TTL ] = time .time ,
91
110
default : t .Any = None ,
92
111
enable_stats : bool = False ,
93
- on_delete : t .Optional [t .Callable [[t .Hashable , t .Any , RemovalCause ], None ]] = None ,
112
+ on_get : T_ON_GET_CALLBACK = None ,
113
+ on_delete : T_ON_DELETE_CALLBACK = None ,
94
114
):
95
115
self .maxsize = maxsize
96
116
self .ttl = ttl
97
117
self .timer = timer
98
118
self .default = default
119
+ self .on_get = on_get
99
120
self .on_delete = on_delete
100
121
self .stats = CacheStatsTracker (self , enable = enable_stats )
101
122
@@ -255,6 +276,7 @@ def get(self, key: t.Hashable, default: t.Any = None) -> t.Any:
255
276
return self ._get (key , default = default )
256
277
257
278
def _get (self , key : t .Hashable , default : t .Any = None ) -> t .Any :
279
+ existed = True
258
280
try :
259
281
value = self ._cache [key ]
260
282
@@ -263,6 +285,7 @@ def _get(self, key: t.Hashable, default: t.Any = None) -> t.Any:
263
285
raise KeyError
264
286
self .stats .inc_hit_count ()
265
287
except KeyError :
288
+ existed = False
266
289
self .stats .inc_miss_count ()
267
290
if default is None :
268
291
default = self .default
@@ -273,6 +296,9 @@ def _get(self, key: t.Hashable, default: t.Any = None) -> t.Any:
273
296
else :
274
297
value = default
275
298
299
+ if self .on_get :
300
+ self .on_get (key , value , existed )
301
+
276
302
return value
277
303
278
304
def get_many (self , iteratee : T_FILTER ) -> dict :
0 commit comments