Registry / serialization / cached-property

cached-property

JSON →
library2.0.1pypypi✓ verified 52d ago

cached-property (current version 2.0.1) is a Python decorator for caching the results of properties in classes. It provides a straightforward way to memoize expensive computations, executing them only once per instance and storing the result as a regular attribute. The library offers basic, thread-safe, and time-based (TTL) caching mechanisms, as well as experimental async/await compatibility. It maintains an active development status with releases typically aligned with Python version support updates.

serializationdatabaseweb-framework
pip install cached-property
Install & Compatibility
Where this runs
tested against v2.0.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.925 runs
installs and imports cleanly · install 0.0s · import 0.208s · 17.8MB
glibc
py 3.103.925 runs
installs and imports cleanly · install 1.5s · import 0.181s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

cached_property
from cached_property import cached_property
threaded_cached_property
from cached_property import threaded_cached_property
cached_property_with_ttl
from cached_property import cached_property_with_ttl
threaded_cached_property_with_ttl
from cached_property import threaded_cached_property_with_ttl

This example demonstrates how to use the `cached_property` decorator to cache an expensive property computation. The `boardwalk` property will only execute its logic once per instance, returning the cached value on subsequent accesses until explicitly invalidated.

from cached_property import cached_property class Monopoly: def __init__(self): self.boardwalk_price = 500 @cached_property def boardwalk(self): # In reality, this might represent a database call or time # intensive task like calling a third-party API. self.boardwalk_price += 50 return self.boardwalk_price monopoly = Monopoly() print(f"First access: {monopoly.boardwalk}") print(f"Second access (cached): {monopoly.boardwalk}") # To invalidate the cache, delete the attribute: del monopoly.__dict__['boardwalk'] # Or del monopoly.boardwalk for simple cases print(f"After invalidation: {monopoly.boardwalk}")
Debug
Known issues
breakingVersion 2.0.0 of `cached-property` officially dropped support for Python versions older than 3.8. Users on Python 2.7 or 3.7 and below should stick to `cached-property` version 1.5.2 or earlier.
fix
Upgrade your Python environment to 3.8+ or pin `cached-property` to a compatible version (e.g., `cached-property<2.0.0` for Python <3.8).
affects: <2.0.0
gotchaPython 3.8+ introduced `functools.cached_property` into the standard library. For basic property caching in Python 3.8+, `functools.cached_property` is generally preferred. `cached-property` provides additional features like time-to-live (TTL) and thread-safe variants that are not present in `functools.cached_property`.
fix
For basic caching in Python 3.8+, consider using `from functools import cached_property`. If you require TTL or explicit thread-safe caching, `cached-property` remains a viable choice.
affects: 2.0.0+
gotchaThe `cached_property_with_ttl` and `threaded_cached_property_with_ttl` functions do not reliably allow manual invalidation of the cache. This means that once a value is cached with a TTL, it might not be possible to force a re-computation before the TTL expires.
fix
Be aware of this limitation when using TTL features. If immediate invalidation is critical, consider using the base `cached_property` and managing invalidation manually (`del obj.property_name`) or designing around the TTL expiration.
affects: 1.0.0+
gotchaWhen combining `asyncio` with threading, especially with the `ttl` versions, be aware that most `asyncio` objects are not thread-safe. Running separate event loops in different threads can lead to unexpected behavior with cached values.
fix
Avoid mixing `asyncio` with threading if possible. If necessary, ensure proper synchronization and careful management of event loops across threads to prevent data corruption or incorrect cached values.
affects: 1.0.0+
gotchaInvalidating a `cached_property` is typically done by deleting the attribute (`del obj.property_name`). The library's quickstart sometimes shows `del obj.__dict__['property_name']` which is equivalent but can be less idiomatic. Both methods clear the cached value, allowing the property method to run again on next access.
fix
Prefer `del obj.property_name` for simple cache invalidation. Ensure your application logic correctly triggers invalidation when the underlying data changes, as the decorator itself does not automatically detect state changes.
affects: 1.0.0+
Errors
Common errors & fixes
ImportError: cannot import name 'cached_property' from 'functools'
This error occurs when attempting to import `cached_property` from Python's built-in `functools` module in a Python version prior to 3.8, where it was not yet available, or when confusing the standard library `cached_property` with the external `cached-property` package.
fix
To use the `cached-property` library (version 2.0.1 requires Python 3.8+), ensure it's installed (`pip install cached-property`) and import it directly: `from cached_property import cached_property`. If you specifically intend to use the standard library `functools.cached_property`, ensure your Python environment is version 3.8 or newer.
AttributeError: 'cached_property' object has no attribute 'setter'
The `cached_property` decorator (both from the external `cached-property` library and `functools`) is designed for properties whose values are computed once and then cached as effectively immutable attributes; it does not inherently support the `.setter` method like a standard `property` decorator.
fix
If you need a writable property with caching, you typically manage cache invalidation manually within a custom setter (e.g., `del self.__dict__['my_property']`) or by defining a standard `@property` with a `@my_property.setter` and implementing explicit caching logic there.
TypeError: Cannot use cached_property instance without calling __set_name__ on it.
This error commonly arises when `cached_property` is used with classes that define `__slots__` but do not include `'__dict__'` in their `__slots__` definition. `cached_property` relies on writing the cached value to the instance's `__dict__`, which is unavailable or immutable in such cases.
fix
To use `cached_property` with `__slots__`, you must include `'__dict__'` in your `__slots__` definition (e.g., `__slots__ = ('my_attribute', '__dict__')`) to provide a mutable dictionary for caching. Alternatively, avoid `__slots__` if memory optimization is not critical, or consider using `functools.lru_cache` on a regular method if applicable.
AttributeError: 'cached_property' object has no attribute 'lock'
This error specifically occurs in Python 3.12 and later versions when code attempts to access an undocumented `lock` attribute on a `cached_property` instance. The internal, class-wide locking mechanism of `functools.cached_property` (which caused performance issues) was removed in Python 3.12.
fix
For thread-safe caching with the `cached-property` library, use the `threaded_cached_property` decorator (`from cached_property import threaded_cached_property`). If you were relying on the removed `functools.cached_property` lock, you must implement explicit locking within your getter function or around access points to ensure thread synchronization.
Upgrade
Version history
2.0.1latest on PyPI
Audit
Dependencies

No dependency data recorded yet.

Agent activity
20 hits · last 30 days
node
8
ahrefsbot
3
seranking-bot
3
Amazon
1
amazonbot
1
Resources