1********************************************************************* 2:mod:`cachetools` --- Extensible memoizing collections and decorators 3********************************************************************* 4 5.. module:: cachetools 6 7This module provides various memoizing collections and decorators, 8including variants of the Python Standard Library's `@lru_cache`_ 9function decorator. 10 11For the purpose of this module, a *cache* is a mutable_ mapping_ of a 12fixed maximum size. When the cache is full, i.e. by adding another 13item the cache would exceed its maximum size, the cache must choose 14which item(s) to discard based on a suitable `cache algorithm`_. In 15general, a cache's size is the total size of its items, and an item's 16size is a property or function of its value, e.g. the result of 17``sys.getsizeof(value)``. For the trivial but common case that each 18item counts as :const:`1`, a cache's size is equal to the number of 19its items, or ``len(cache)``. 20 21Multiple cache classes based on different caching algorithms are 22implemented, and decorators for easily memoizing function and method 23calls are provided, too. 24 25 26.. testsetup:: * 27 28 import operator 29 from cachetools import cached, cachedmethod, LRUCache, TTLCache 30 31 from unittest import mock 32 urllib = mock.MagicMock() 33 34 35Cache implementations 36===================== 37 38This module provides several classes implementing caches using 39different cache algorithms. All these classes derive from class 40:class:`Cache`, which in turn derives from 41:class:`collections.MutableMapping`, and provide :attr:`maxsize` and 42:attr:`currsize` properties to retrieve the maximum and current size 43of the cache. When a cache is full, :meth:`Cache.__setitem__()` calls 44:meth:`self.popitem()` repeatedly until there is enough room for the 45item to be added. 46 47:class:`Cache` also features a :meth:`getsizeof` method, which returns 48the size of a given `value`. The default implementation of 49:meth:`getsizeof` returns :const:`1` irrespective of its argument, 50making the cache's size equal to the number of its items, or 51``len(cache)``. For convenience, all cache classes accept an optional 52named constructor parameter `getsizeof`, which may specify a function 53of one argument used to retrieve the size of an item's value. 54 55Note that the values of a :class:`Cache` are mutable by default, as 56are e.g. the values of a :class:`dict`. It is the user's 57responsibility to take care that cached values are not accidentally 58modified. This is especially important when using a custom 59`getsizeof` function, since the size of an item's value will only be 60computed when the item is inserted into the cache. 61 62.. note:: 63 64 Please be aware that all these classes are *not* thread-safe. 65 Access to a shared cache from multiple threads must be properly 66 synchronized, e.g. by using one of the memoizing decorators with a 67 suitable `lock` object. 68 69.. autoclass:: Cache(maxsize, getsizeof=None) 70 :members: currsize, getsizeof, maxsize 71 72 This class discards arbitrary items using :meth:`popitem` to make 73 space when necessary. Derived classes may override :meth:`popitem` 74 to implement specific caching strategies. If a subclass has to 75 keep track of item access, insertion or deletion, it may 76 additionally need to override :meth:`__getitem__`, 77 :meth:`__setitem__` and :meth:`__delitem__`. 78 79.. autoclass:: FIFOCache(maxsize, getsizeof=None) 80 :members: popitem 81 82 This class evicts items in the order they were added to make space 83 when necessary. 84 85.. autoclass:: LFUCache(maxsize, getsizeof=None) 86 :members: popitem 87 88 This class counts how often an item is retrieved, and discards the 89 items used least often to make space when necessary. 90 91.. autoclass:: LRUCache(maxsize, getsizeof=None) 92 :members: popitem 93 94 This class discards the least recently used items first to make 95 space when necessary. 96 97.. autoclass:: MRUCache(maxsize, getsizeof=None) 98 :members: popitem 99 100 This class discards the most recently used items first to make 101 space when necessary. 102 103.. autoclass:: RRCache(maxsize, choice=random.choice, getsizeof=None) 104 :members: choice, popitem 105 106 This class randomly selects candidate items and discards them to 107 make space when necessary. 108 109 By default, items are selected from the list of cache keys using 110 :func:`random.choice`. The optional argument `choice` may specify 111 an alternative function that returns an arbitrary element from a 112 non-empty sequence. 113 114.. autoclass:: TTLCache(maxsize, ttl, timer=time.monotonic, getsizeof=None) 115 :members: popitem, timer, ttl 116 117 This class associates a time-to-live value with each item. Items 118 that expire because they have exceeded their time-to-live will be 119 no longer accessible, and will be removed eventually. If no 120 expired items are there to remove, the least recently used items 121 will be discarded first to make space when necessary. 122 123 By default, the time-to-live is specified in seconds and 124 :func:`time.monotonic` is used to retrieve the current time. A 125 custom `timer` function can also be supplied: 126 127 .. testcode:: 128 129 from datetime import datetime, timedelta 130 131 cache = TTLCache(maxsize=10, ttl=timedelta(hours=12), timer=datetime.now) 132 133 The expression `timer() + ttl` at the time of insertion defines the 134 expiration time of a cache item, and must be comparable against 135 later results of `timer()`. 136 137 .. method:: expire(self, time=None) 138 139 Expired items will be removed from a cache only at the next 140 mutating operation, e.g. :meth:`__setitem__` or 141 :meth:`__delitem__`, and therefore may still claim memory. 142 Calling this method removes all items whose time-to-live would 143 have expired by `time`, so garbage collection is free to reuse 144 their memory. If `time` is :const:`None`, this removes all 145 items that have expired by the current value returned by 146 :attr:`timer`. 147 148 149Extending cache classes 150----------------------- 151 152Sometimes it may be desirable to notice when and what cache items are 153evicted, i.e. removed from a cache to make room for new items. Since 154all cache implementations call :meth:`popitem` to evict items from the 155cache, this can be achieved by overriding this method in a subclass: 156 157.. doctest:: 158 :pyversion: >= 3 159 160 >>> class MyCache(LRUCache): 161 ... def popitem(self): 162 ... key, value = super().popitem() 163 ... print('Key "%s" evicted with value "%s"' % (key, value)) 164 ... return key, value 165 166 >>> c = MyCache(maxsize=2) 167 >>> c['a'] = 1 168 >>> c['b'] = 2 169 >>> c['c'] = 3 170 Key "a" evicted with value "1" 171 172Similar to the standard library's :class:`collections.defaultdict`, 173subclasses of :class:`Cache` may implement a :meth:`__missing__` 174method which is called by :meth:`Cache.__getitem__` if the requested 175key is not found: 176 177.. doctest:: 178 :pyversion: >= 3 179 180 >>> class PepStore(LRUCache): 181 ... def __missing__(self, key): 182 ... """Retrieve text of a Python Enhancement Proposal""" 183 ... url = 'http://www.python.org/dev/peps/pep-%04d/' % key 184 ... with urllib.request.urlopen(url) as s: 185 ... pep = s.read() 186 ... self[key] = pep # store text in cache 187 ... return pep 188 189 >>> peps = PepStore(maxsize=4) 190 >>> for n in 8, 9, 290, 308, 320, 8, 218, 320, 279, 289, 320: 191 ... pep = peps[n] 192 >>> print(sorted(peps.keys())) 193 [218, 279, 289, 320] 194 195Note, though, that such a class does not really behave like a *cache* 196any more, and will lead to surprising results when used with any of 197the memoizing decorators described below. However, it may be useful 198in its own right. 199 200 201Memoizing decorators 202==================== 203 204The :mod:`cachetools` module provides decorators for memoizing 205function and method calls. This can save time when a function is 206often called with the same arguments: 207 208.. doctest:: 209 210 >>> @cached(cache={}) 211 ... def fib(n): 212 ... 'Compute the nth number in the Fibonacci sequence' 213 ... return n if n < 2 else fib(n - 1) + fib(n - 2) 214 215 >>> fib(42) 216 267914296 217 218.. decorator:: cached(cache, key=cachetools.keys.hashkey, lock=None) 219 220 Decorator to wrap a function with a memoizing callable that saves 221 results in a cache. 222 223 The `cache` argument specifies a cache object to store previous 224 function arguments and return values. Note that `cache` need not 225 be an instance of the cache implementations provided by the 226 :mod:`cachetools` module. :func:`cached` will work with any 227 mutable mapping type, including plain :class:`dict` and 228 :class:`weakref.WeakValueDictionary`. 229 230 `key` specifies a function that will be called with the same 231 positional and keyword arguments as the wrapped function itself, 232 and which has to return a suitable cache key. Since caches are 233 mappings, the object returned by `key` must be hashable. The 234 default is to call :func:`cachetools.keys.hashkey`. 235 236 If `lock` is not :const:`None`, it must specify an object 237 implementing the `context manager`_ protocol. Any access to the 238 cache will then be nested in a ``with lock:`` statement. This can 239 be used for synchronizing thread access to the cache by providing a 240 :class:`threading.Lock` instance, for example. 241 242 .. note:: 243 244 The `lock` context manager is used only to guard access to the 245 cache object. The underlying wrapped function will be called 246 outside the `with` statement, and must be thread-safe by itself. 247 248 The original underlying function is accessible through the 249 :attr:`__wrapped__` attribute of the memoizing wrapper function. 250 This can be used for introspection or for bypassing the cache. 251 252 To perform operations on the cache object, for example to clear the 253 cache during runtime, the cache should be assigned to a variable. 254 When a `lock` object is used, any access to the cache from outside 255 the function wrapper should also be performed within an appropriate 256 `with` statement: 257 258 .. testcode:: 259 260 from cachetools.keys import hashkey 261 from threading import Lock 262 263 cache = LRUCache(maxsize=32) 264 lock = Lock() 265 266 @cached(cache, key=hashkey, lock=lock) 267 def get_pep(num): 268 'Retrieve text of a Python Enhancement Proposal' 269 url = 'http://www.python.org/dev/peps/pep-%04d/' % num 270 with urllib.request.urlopen(url) as s: 271 return s.read() 272 273 # make sure access to cache is synchronized 274 with lock: 275 cache.clear() 276 277 # always use the key function for accessing cache items 278 with lock: 279 cache.pop(hashkey(42), None) 280 281 It is also possible to use a single shared cache object with 282 multiple functions. However, care must be taken that different 283 cache keys are generated for each function, even for identical 284 function arguments: 285 286 .. doctest:: 287 :options: +ELLIPSIS 288 289 >>> from cachetools.keys import hashkey 290 >>> from functools import partial 291 292 >>> # shared cache for integer sequences 293 >>> numcache = {} 294 295 >>> # compute Fibonacci numbers 296 >>> @cached(numcache, key=partial(hashkey, 'fib')) 297 ... def fib(n): 298 ... return n if n < 2 else fib(n - 1) + fib(n - 2) 299 300 >>> # compute Lucas numbers 301 >>> @cached(numcache, key=partial(hashkey, 'luc')) 302 ... def luc(n): 303 ... return 2 - n if n < 2 else luc(n - 1) + luc(n - 2) 304 305 >>> fib(42) 306 267914296 307 >>> luc(42) 308 599074578 309 >>> list(sorted(numcache.items())) 310 [..., (('fib', 42), 267914296), ..., (('luc', 42), 599074578)] 311 312 313.. decorator:: cachedmethod(cache, key=cachetools.keys.hashkey, lock=None) 314 315 Decorator to wrap a class or instance method with a memoizing 316 callable that saves results in a (possibly shared) cache. 317 318 The main difference between this and the :func:`cached` function 319 decorator is that `cache` and `lock` are not passed objects, but 320 functions. Both will be called with :const:`self` (or :const:`cls` 321 for class methods) as their sole argument to retrieve the cache or 322 lock object for the method's respective instance or class. 323 324 .. note:: 325 326 As with :func:`cached`, the context manager obtained by calling 327 ``lock(self)`` will only guard access to the cache itself. It 328 is the user's responsibility to handle concurrent calls to the 329 underlying wrapped method in a multithreaded environment. 330 331 One advantage of :func:`cachedmethod` over the :func:`cached` 332 function decorator is that cache properties such as `maxsize` can 333 be set at runtime: 334 335 .. testcode:: 336 337 class CachedPEPs(object): 338 339 def __init__(self, cachesize): 340 self.cache = LRUCache(maxsize=cachesize) 341 342 @cachedmethod(operator.attrgetter('cache')) 343 def get(self, num): 344 """Retrieve text of a Python Enhancement Proposal""" 345 url = 'http://www.python.org/dev/peps/pep-%04d/' % num 346 with urllib.request.urlopen(url) as s: 347 return s.read() 348 349 peps = CachedPEPs(cachesize=10) 350 print("PEP #1: %s" % peps.get(1)) 351 352 .. testoutput:: 353 :hide: 354 :options: +ELLIPSIS 355 356 PEP #1: ... 357 358 359 When using a shared cache for multiple methods, be aware that 360 different cache keys must be created for each method even when 361 function arguments are the same, just as with the `@cached` 362 decorator: 363 364 .. testcode:: 365 366 class CachedReferences(object): 367 368 def __init__(self, cachesize): 369 self.cache = LRUCache(maxsize=cachesize) 370 371 @cachedmethod(lambda self: self.cache, key=partial(hashkey, 'pep')) 372 def get_pep(self, num): 373 """Retrieve text of a Python Enhancement Proposal""" 374 url = 'http://www.python.org/dev/peps/pep-%04d/' % num 375 with urllib.request.urlopen(url) as s: 376 return s.read() 377 378 @cachedmethod(lambda self: self.cache, key=partial(hashkey, 'rfc')) 379 def get_rfc(self, num): 380 """Retrieve text of an IETF Request for Comments""" 381 url = 'https://tools.ietf.org/rfc/rfc%d.txt' % num 382 with urllib.request.urlopen(url) as s: 383 return s.read() 384 385 docs = CachedReferences(cachesize=100) 386 print("PEP #1: %s" % docs.get_pep(1)) 387 print("RFC #1: %s" % docs.get_rfc(1)) 388 389 .. testoutput:: 390 :hide: 391 :options: +ELLIPSIS 392 393 PEP #1: ... 394 RFC #1: ... 395 396 397***************************************************************** 398:mod:`cachetools.keys` --- Key functions for memoizing decorators 399***************************************************************** 400 401.. module:: cachetools.keys 402 403This module provides several functions that can be used as key 404functions with the :func:`cached` and :func:`cachedmethod` decorators: 405 406.. autofunction:: hashkey 407 408 This function returns a :class:`tuple` instance suitable as a cache 409 key, provided the positional and keywords arguments are hashable. 410 411.. autofunction:: typedkey 412 413 This function is similar to :func:`hashkey`, but arguments of 414 different types will yield distinct cache keys. For example, 415 ``typedkey(3)`` and ``typedkey(3.0)`` will return different 416 results. 417 418These functions can also be helpful when implementing custom key 419functions for handling some non-hashable arguments. For example, 420calling the following function with a dictionary as its `env` argument 421will raise a :class:`TypeError`, since :class:`dict` is not hashable:: 422 423 @cached(LRUCache(maxsize=128)) 424 def foo(x, y, z, env={}): 425 pass 426 427However, if `env` always holds only hashable values itself, a custom 428key function can be written that handles the `env` keyword argument 429specially:: 430 431 def envkey(*args, env={}, **kwargs): 432 key = hashkey(*args, **kwargs) 433 key += tuple(sorted(env.items())) 434 return key 435 436The :func:`envkey` function can then be used in decorator declarations 437like this:: 438 439 @cached(LRUCache(maxsize=128), key=envkey) 440 def foo(x, y, z, env={}): 441 pass 442 443 foo(1, 2, 3, env=dict(a='a', b='b')) 444 445 446**************************************************************************** 447:mod:`cachetools.func` --- :func:`functools.lru_cache` compatible decorators 448**************************************************************************** 449 450.. module:: cachetools.func 451 452To ease migration from (or to) Python 3's :func:`functools.lru_cache`, 453this module provides several memoizing function decorators with a 454similar API. All these decorators wrap a function with a memoizing 455callable that saves up to the `maxsize` most recent calls, using 456different caching strategies. If `maxsize` is set to :const:`None`, 457the caching strategy is effectively disabled and the cache can grow 458without bound. 459 460If the optional argument `typed` is set to :const:`True`, function 461arguments of different types will be cached separately. For example, 462``f(3)`` and ``f(3.0)`` will be treated as distinct calls with 463distinct results. 464 465If a `user_function` is specified instead, it must be a callable. 466This allows the decorator to be applied directly to a user function, 467leaving the `maxsize` at its default value of 128:: 468 469 @cachetools.func.lru_cache 470 def count_vowels(sentence): 471 sentence = sentence.casefold() 472 return sum(sentence.count(vowel) for vowel in 'aeiou') 473 474The wrapped function is instrumented with a :func:`cache_parameters` 475function that returns a new :class:`dict` showing the values for 476`maxsize` and `typed`. This is for information purposes only. 477Mutating the values has no effect. 478 479The wrapped function is also instrumented with :func:`cache_info` and 480:func:`cache_clear` functions to provide information about cache 481performance and clear the cache. Please see the 482:func:`functools.lru_cache` documentation for details. Also note that 483all the decorators in this module are thread-safe by default. 484 485 486.. decorator:: fifo_cache(user_function) 487 fifo_cache(maxsize=128, typed=False) 488 489 Decorator that wraps a function with a memoizing callable that 490 saves up to `maxsize` results based on a First In First Out 491 (FIFO) algorithm. 492 493.. decorator:: lfu_cache(user_function) 494 lfu_cache(maxsize=128, typed=False) 495 496 Decorator that wraps a function with a memoizing callable that 497 saves up to `maxsize` results based on a Least Frequently Used 498 (LFU) algorithm. 499 500.. decorator:: lru_cache(user_function) 501 lru_cache(maxsize=128, typed=False) 502 503 Decorator that wraps a function with a memoizing callable that 504 saves up to `maxsize` results based on a Least Recently Used (LRU) 505 algorithm. 506 507.. decorator:: mru_cache(user_function) 508 mru_cache(maxsize=128, typed=False) 509 510 Decorator that wraps a function with a memoizing callable that 511 saves up to `maxsize` results based on a Most Recently Used (MRU) 512 algorithm. 513 514.. decorator:: rr_cache(user_function) 515 rr_cache(maxsize=128, choice=random.choice, typed=False) 516 517 Decorator that wraps a function with a memoizing callable that 518 saves up to `maxsize` results based on a Random Replacement (RR) 519 algorithm. 520 521.. decorator:: ttl_cache(user_function) 522 ttl_cache(maxsize=128, ttl=600, timer=time.monotonic, typed=False) 523 524 Decorator to wrap a function with a memoizing callable that saves 525 up to `maxsize` results based on a Least Recently Used (LRU) 526 algorithm with a per-item time-to-live (TTL) value. 527 528 529.. _@lru_cache: http://docs.python.org/3/library/functools.html#functools.lru_cache 530.. _cache algorithm: http://en.wikipedia.org/wiki/Cache_algorithms 531.. _context manager: http://docs.python.org/dev/glossary.html#term-context-manager 532.. _mapping: http://docs.python.org/dev/glossary.html#term-mapping 533.. _mutable: http://docs.python.org/dev/glossary.html#term-mutable 534