{"id":313,"library":"cachetools","title":"cachetools: Extensible Memoizing Collections and Decorators","description":"Provides various memoizing collections and decorators, including variants of Python's @lru_cache function decorator. Current version: 7.0.5. Release cadence: Regular updates with new features and improvements.","status":"active","version":"7.0.5","language":"python","source_language":"en","source_url":"https://github.com/tkem/cachetools","tags":["memoization","caching","decorators","Python"],"install":[{"cmd":"pip install cachetools","lang":"bash","label":"Install cachetools"}],"dependencies":[{"reason":"Provides the MutableMapping base class for cache implementations.","package":"collections.abc"}],"imports":[{"note":"Cache is the base class for all cache implementations.","symbol":"Cache","correct":"from cachetools import Cache"},{"note":"LRUCache is a cache implementation that discards the least recently used items.","symbol":"LRUCache","correct":"from cachetools import LRUCache"},{"note":"cached is a decorator for memoizing function calls.","symbol":"cached","correct":"from cachetools import cached"}],"quickstart":{"code":"import os\nfrom cachetools import cached, LRUCache\n\n# Initialize a cache with a maximum size of 128\ncache = LRUCache(maxsize=128)\n\n@cached(cache)\ndef fib(n):\n    if n < 2:\n        return n\n    return fib(n - 1) + fib(n - 2)\n\n# Compute the 42nd Fibonacci number\nprint(fib(42))","lang":"python","description":"A simple example demonstrating the use of cachetools to memoize Fibonacci number calculations."},"warnings":[{"fix":"Ensure that the cache function always returns a valid cache object.","message":"Support for cache(self) returning None to suppress any caching has been deprecated. cache(self) should always return a valid cache object.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Replace 'typed=True' with 'key=typedkey' in the cached decorator.","message":"The typed argument in the cached decorator is deprecated. Use key=typedkey instead.","severity":"deprecated","affected_versions":">=1.1.0"},{"fix":"Use a suitable lock object when accessing the cache from multiple threads.","message":"Access to a shared cache from multiple threads must be properly synchronized to avoid concurrency issues.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use a virtual environment for installing Python packages to avoid permission issues and conflicts with the system package manager.","message":"Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Investigate the meaning of the numerical output `267914296` in the context of the executed test to determine the actual failure mode. If it represents an unexpected return value, compare it against expected behavior for the specific library/function being tested.","message":"The provided test output does not contain a clear error message or stack trace that can be mapped to a specific library behavior change or issue.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T13:00:15.587Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Run `pip install cachetools` in your terminal to install the package.","cause":"The 'cachetools' library has not been installed in your Python environment.","error":"ModuleNotFoundError: No module named 'cachetools'"},{"fix":"When using cache decorators like `@cached` or `@ttl_cache`, provide a suitable `lock` object (e.g., `lock=threading.Lock()`) for thread-safe operations. If manually managing a cache instance, wrap access with explicit locking using `threading.Lock`.","cause":"This often occurs in multi-threaded environments when a cache is accessed concurrently without proper synchronization, or when an item is requested after its Time-To-Live (TTL) has expired and it's been removed (or is being removed) by another thread. The base cache classes are not inherently thread-safe.","error":"KeyError"},{"fix":"Provide a custom `key` function to the cache decorator (e.g., `@cached(cache=LRUCache(maxsize=128), key=cachetools.keys.hashkey)`) to transform unhashable arguments into a hashable representation, such as a tuple of sorted items or a unique identifier.","cause":"Cache keys or function arguments used for caching must be hashable. Python dictionaries are mutable and therefore not hashable by default, leading to this error if passed directly as a key or argument without a custom key function.","error":"TypeError: unhashable type: 'dict'"},{"fix":"Import the specific cache decorator or class directly from the `cachetools` module (e.g., `from cachetools import cached, LRUCache, TTLCache`) and use them as `@cached(cache=LRUCache(...))` or `@ttl_cache(...)`.","cause":"This error typically indicates an attempt to access cache decorators (like `lru_cache` or `ttl_cache`) via an outdated import path (`cachetools.func`). In current versions, these decorators are generally imported directly from the `cachetools` module or used via the `cached` decorator with a cache instance.","error":"AttributeError: module 'cachetools' has no attribute 'func'"},{"fix":"Ensure that the `missing` factory function provided to the cache returns the expected mutable type (e.g., a list `missing=lambda k: []` if you intend to use list methods) or handle the returned dictionary type appropriately without calling list methods on it.","cause":"This occurs when an `LRUCache` (or similar) is initialized with a `missing` function that returns a dictionary, but the user then tries to apply a list-specific method like `append` to a value retrieved from that cache, expecting a list instead of a dictionary.","error":"AttributeError: 'dict' object has no attribute 'append'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"17.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"11.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"17.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.3,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}