fix(litestar): key the filter dependency cache on dep_defaults too - #786
Open
ruicleite96 wants to merge 1 commit into
Open
fix(litestar): key the filter dependency cache on dep_defaults too#786ruicleite96 wants to merge 1 commit into
ruicleite96 wants to merge 1 commit into
Conversation
`create_filter_dependencies` keyed on the config alone, but `dep_defaults` shapes the dependencies just as much — it names all seven of them and supplies the default page size. Two callers passing the same config with different defaults therefore shared one set, and whichever was built first won for the whole process: a caller asking for `DEFAULT_PAGINATION_SIZE = 100` silently served 20, and one renaming `LIMIT_OFFSET_FILTER_DEPENDENCY_KEY` got the previous caller's key instead of its own. Key by the defaults' values rather than the instance, so two equal `DependencyDefaults` still share one set and the cache stays useful.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #786 +/- ##
==========================================
+ Coverage 82.43% 82.45% +0.02%
==========================================
Files 105 105
Lines 9039 9042 +3
Branches 1219 1219
==========================================
+ Hits 7451 7456 +5
+ Misses 1262 1260 -2
Partials 326 326 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Problem
create_filter_dependencieskeys its cache on the config alone:but
dep_defaultsshapes the generated dependencies just as much. It suppliesDEFAULT_PAGINATION_SIZEand names all seven dependencies in the returned dict, and the function reads eight of its attributes while building them.So two callers passing the same config with different defaults share one set, and whichever was built first wins for the whole process:
Reversing the build order flips it: the caller who wanted the stock 20 gets 100 instead. Renaming a dependency key fails the same way — a caller overriding
LIMIT_OFFSET_FILTER_DEPENDENCY_KEYis handed the previous caller's key and its own is simply absent from the dict, so resolution fails or silently binds nothing.This is quiet: the app starts, the dependencies exist, and they are configured for somebody else.
Change
Build the key from the defaults' values alongside the config. Keying by value rather than by instance matters — keying on the object would make every explicit
dep_defaultsa cache miss and defeat the cache entirely, so two equalDependencyDefaultsstill share one set.Scope
The FastAPI provider had the same defect and is fixed in #784. This is the Litestar half, which I kept separate so each stays scoped to one extension; the two do not touch the same files and can land in either order.
Note that the other problem #784 fixes — a module-level aggregate function whose
__signature__was rewritten per config — does not affect Litestar. Itsprovide_filtersis defined inside_create_filter_aggregate_function(providers.py:745), so it is already a fresh function per config. I checked by building the dependencies rather than by reading:{"search": "name"}and{"created_at": True}correctly yield['search_filter']and['created_filter'].Tests
tests/unit/test_extensions/test_litestar/test_provider_cache_defaults.py:dep_defaultsgets two dependency sets, each with its own page size;DependencyDefaultsstill share one set, so the fix does not defeat the cache;The first and third fail on
mainand pass here; the second passes both ways and is there to pin that the cache still works.Full
tests/unit/test_extensions/passes (606).ruff check,ruff format,mypy,pyrightandslotscheckare clean.📚 Documentation preview: https://litestar-org.github.io/advanced-alchemy-docs-preview/786