Add key parameter for custom cache key computation#782
Add key parameter for custom cache key computation#782rodrigobnogueira wants to merge 7 commits into
Conversation
The optional key callable receives the call arguments and returns the cache key, letting callers exclude arguments that do not affect the result, such as a DB connection passed alongside a query (#619). The same computation backs the call, cache_invalidate and cache_contains paths. typed=True with key raises ValueError since typed only affects the default key computation. With key unset the behavior is unchanged.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #782 +/- ##
==========================================
+ Coverage 97.78% 97.96% +0.17%
==========================================
Files 16 17 +1
Lines 1176 1279 +103
Branches 61 66 +5
==========================================
+ Hits 1150 1253 +103
Misses 23 23
Partials 3 3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will not alter performance
Comparing Footnotes
|
An extra method call is measurable on cache_invalidate, which CodSpeed put at about 21 percent; branching inline on the stored key keeps the default path at parity with master.
Vizonex
left a comment
There was a problem hiding this comment.
Overall great job, I'll see if we can get this approved or merged.
|
Thanks @Vizonex |
Not really. It just suggested a different implementation. |
Fair 🙏 |
When no custom key is given, __init__ wraps functools._make_key in a packing lambda so __key is always callable, and the None branches in __call__, cache_invalidate and cache_contains collapse to a single call, as suggested in review. The default path gains one call layer; CodSpeed will show whether it is measurable.
This reverts commit ad09f79.
What do these changes do?
Add an optional
keyparameter toalru_cachefor custom cache key computation, so arguments that do not affect the result can be excluded from the key (the motivating case in #619: a DB connection passed alongside a query). The callable receives the same arguments as the wrapped function and its hashable result replaces the defaultfunctools._make_keytuple.cache_invalidate()andcache_contains()compute keys the same way, so a custom key invalidates exactly what it cached.typed=Truecombined withkeyraisesValueError, sincetypedonly affects the default computation. Withkeyunset (the default), behavior is unchanged, keeping the stdlib-mirroring interface intact; the README documents the parameter as an async-lru extension beyond thelru_cacheinterface.On the stdlib-compatibility question from the issue discussion: there was an upstream proposal, python/cpython#90780 (bpo-46622, 2022), which was closed in favor of a separate implementation rather than extending
lru_cacheto coroutines; thefunctoolsdocs were later amended (python/cpython#107619) to note that caching async functions withlru_cache"doesn't make sense". Whatever shape a future stdlib solution might take, reconciling stays easy becausekey=Nonekeeps the mirror exact.Are there changes in behavior for the user?
Only when the new parameter is used. Without
key, everything is unchanged.Is it a substantial burden for the maintainers to support this?
No. The feature is a single code path shared by the three key computation sites and is fully covered by tests.
Related issue number
Fixes #619
Checklist