cachetools provides extensible memoizing collections and decorators, including variants of Python's @lru_cache. Pure Python 3.10+, no external runtime dependencies.
Cache (a MutableMapping with maxsize, currsize, and getsizeof)__setitem__, __getitem__, __delitem__, and popitem() to implement eviction policiescache_setitem=Cache.__setitem__) to call parent methods efficiently while avoiding recursionFIFOCache: Evicts oldest inserted (OrderedDict)LRUCache: Evicts least recently used (OrderedDict.move_to_end())LFUCache: Evicts least frequently used (doubly-linked list of frequency buckets)RRCache: Random eviction (__keys list with __index dict for O(1) removal)TTLCache/TLRUCache: Time-based eviction via _TimedCache base; _Timer context manager freezes time during operations to prevent TOCTOU bugs; expire() returns list[tuple[key, value]]@cached (_cached.py): Function memoization; separate wrappers for each lock/condition/info combination; supports cache=None via _uncached/_uncached_info wrappers (pass-through without caching)@cachedmethod (_cachedmethod.py): Method memoization via descriptor protocol (__set_name__/__get__); class hierarchy: _WrapperBase (per-instance callable) → _DescriptorBase (descriptor with __set_name__/__get__, replaces self in instance __dict__ via setdefault for thread safety) → _DeprecatedDescriptorBase (backward-compatible @classmethod support with warnings); the backward-compatible _condition variant uses weakref.WeakKeyDictionary for per-instance pending setskey, lock, condition, and info parameters; when condition is given without lock, condition serves as both lock and conditioninfo=True adds cache_info()/cache_clear(); info=False (default) only provides cache_clear()func.py: functools.lru_cache-compatible wrappers; all use threading.Condition() by default for thread safety + stampede prevention; _UnboundTTLCache extends TTLCache with math.inf maxsize for maxsize=None3-tier locking: Unlocked | Locked (release during compute) | Condition (lock + pending set + wait_for/notify_all to prevent thundering herd)
_AbstractCondition protocol in __init__.pyi: extends AbstractContextManager[Any] + Protocol with wait(), wait_for(), notify(), notify_all(). Only wait_for() and notify_all() are used at runtime.
keys.py)hashkey: Default key function; _HashedTuple caches hash valuesmethodkey: Drops self from key; typedkey/typedmethodkey: Adds type() infopytest # Run all tests pytest --cov=cachetools --cov-report term-missing # With coverage tox -e py # Just tests tox -e ruff # Linting (ruff check) tox -e ruff-format # Format check (ruff format --diff) tox -e pyright # Type checking tox -e docs # Build docs tox -e doctest # Run doctests
tests/__init__.py: CacheTestMixin (16 standard tests), _TestCaseProtocol, CountedLock, CountedCondition (implements full _AbstractCondition protocol)unittest.TestCase + CacheTestMixintest_cached.py / test_cachedmethod.py use DecoratorTestMixin / MethodDecoratorTestMixin for all lock/condition/info combosTHREADING_TESTS env var (enabled in tox.ini via setenv)tox -e ruff-format, tox -e ruff)Cache or _TimedCache__setitem__, __delitem__, popitem() (optionally __getitem__)def __setitem__(self, key, value, cache_setitem=Cache.__setitem__)__missing__ edge case: check if key in self after parent callCacheTestMixinInline stubs ship with the package (py.typed marker):
@overload distinguishes info=True vs info=False; Literal[False] overload listed last_TimedCache uses Generic[_KT, _VT, _TT] with _TT defaulting to float_AbstractCondition is @type_check_only Protocol for condition params and cache_condition attributes_cached_wrapper / _cachedmethod_wrapper use ParamSpec(_P) to preserve decorated function signatures; __call__ uses _P.args/_P.kwargs_cachedmethod_wrapper models the descriptor protocol: __set_name__, __get__, __call__; uses Concatenate[Any, _P] so _P excludes self_cachedmethod.py uses # type: ignore for functools.update_wrapper() (typeshed #9846)tox -e pyrightsrc/cachetools/__init__.py — All cache implementationssrc/cachetools/__init__.pyi — Type stubs for caches and decoratorssrc/cachetools/_cached.py — @cached decorator variantssrc/cachetools/_cachedmethod.py — @cachedmethod descriptor variantssrc/cachetools/keys.py / keys.pyi — Key functionssrc/cachetools/func.py / func.pyi — Functools-compatible wrappers (lru_cache, ttl_cache, etc.)tests/__init__.py — Test mixin and helperspyproject.toml — Build config, version: {attr = "cachetools.__version__"}