Add under_cached_property_with_name and under_cache_name (#200)#230
Draft
aiolibsbot wants to merge 3 commits into
Draft
Add under_cached_property_with_name and under_cache_name (#200)#230aiolibsbot wants to merge 3 commits into
aiolibsbot wants to merge 3 commits into
Conversation
Adds a variant of ``under_cached_property`` whose cache attribute name is configurable, plus a decorator-factory class that binds the attribute name once for reuse across many class definitions. The new descriptor unlocks use cases that the existing ``under_cached_property`` could not support, notably classes that define ``__slots__`` and want to share a single cache dict layout across instances. Both pure-Python and Cython implementations are provided to keep the attribute-lookup hot path on par with the existing under_cached_property.
for more information, see https://pre-commit.ci
| self.cache_name = cache_name | ||
|
|
||
| @overload | ||
| def __get__(self, inst: None, owner: type[object] | None = None) -> Self: ... |
| def __get__(self, inst: None, owner: type[object] | None = None) -> Self: ... | ||
|
|
||
| @overload | ||
| def __get__(self, inst: object, owner: type[object] | None = None) -> _T: ... |
| class _CacheNameFactory(Protocol): | ||
| def __call__( | ||
| self, wrapped: Callable[[Any], _T_co] | ||
| ) -> "under_cached_property_with_name[_T_co]": ... |
| @staticmethod | ||
| def under_cached_property_with_name( | ||
| func: Callable[[Any], _T_co], cache_name: str | ||
| ) -> "under_cached_property_with_name[_T_co]": ... |
| ) -> "under_cached_property_with_name[_T_co]": ... | ||
|
|
||
| @staticmethod | ||
| def under_cache_name(name: str) -> _CacheNameFactory: ... |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #230 +/- ##
==========================================
+ Coverage 97.72% 97.76% +0.03%
==========================================
Files 17 18 +1
Lines 881 1076 +195
Branches 44 67 +23
==========================================
+ Hits 861 1052 +191
Misses 12 12
- Partials 8 12 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Vizonex
approved these changes
May 19, 2026
Member
Vizonex
left a comment
There was a problem hiding this comment.
Surprised to see that my idea is being implemented here. I have no complaints about this since this was something I thought would be good for developers who need for a more beginner friendly interface.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Implements GH-200: adds a variant of
under_cached_propertywhose cache attribute name is configurable, plus a decorator-factory class for binding the attribute name once and reusing it.Why
under_cached_propertyis hard-coded to read/writeinst._cache. Several patterns can't use it as-is:__slots__-based classes that want a slot name other than_cache(e.g. to avoid clashes with the underscored cache attribute naming convention of parent classes).The requester (GH-200) provided a concrete sketch of two new classes; this PR is a cleaned-up implementation of that idea.
How
Two new public symbols are exported from
propcache.api(and re-exported at top level):under_cached_property_with_name(wrapped, cache_name)— descriptor identical in behavior tounder_cached_propertyexcept it looks up the cache viagetattr(inst, cache_name)instead ofinst._cache.under_cache_name(cache_name)— decorator factory that binds a cache name once. Calling an instance with a function returns anunder_cached_property_with_namealready wired to that attribute. Implemented as a class (not a closure) so the Cython implementation can keep the call cheap, per the requester's note.Both implementations live in
_helpers_py.pyand_helpers_c.pyxso the C-extension path is on par withunder_cached_property. The dispatch in_helpers.pyand the public surface inapi.py/__init__.pymirror the existing pattern.Testing
tests/test_under_cached_property_with_name.pycovers: basic decoration, caching idempotency, read-only__set__, missing cache attribute, multiple isolated buckets, direct descriptor construction,__slots__compatibility, and the factory'scache_nameattribute.test_api.pyandtest_init.pyextended to assert the new symbols are reachable throughpropcache.apiand the top-levelpropcachefacade.pytest tests/— 63 passed, 4 codspeed-only tests skipped.pre-commit runclean (ruff, pyupgrade, mypy-strict, cython-lint, codespell).Notes for reviewers
under_prefix convention; happy to rename if you'd prefer a shorter symbol likereifyorcached_in.getattr(inst, self.cache_name)so subclasses can override with a property if they need lazy initialization — happy to switch to a faster direct__dict__lookup if that trade-off is unwelcome.Closes #200.
Quality Report
Changes: 10 files changed, 459 insertions(+), 5 deletions(-)
Code scan: clean
Tests: failed (FAILED)
Branch hygiene: clean
Generated by Kōan post-mission quality pipeline