]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
♻️ Update the lru_cache limit for dependencies to account for large apps (#16062)
authorSebastián Ramírez <tiangolo@gmail.com>
Mon, 27 Jul 2026 11:18:26 +0000 (13:18 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Jul 2026 11:18:26 +0000 (11:18 +0000)
fastapi/dependencies/models.py
tests/test_dependency_models.py

index 3ae682cb396099d196d2db11bc26e3e07b345a30..58eae0eafb5555fe7e4742fc236eda8c84a518f9 100644 (file)
@@ -52,6 +52,7 @@ class Dependant:
 
 
 _UsesScopesCache = dict[int, tuple[Dependant, bool]]
+_CALLABLE_CLASSIFICATION_CACHE_SIZE = 4096
 
 
 class _CallIdentity:
@@ -137,7 +138,7 @@ def _get_security_dependencies(*, dependant: Dependant) -> list[Dependant]:
     return [dep for dep in dependant.dependencies if _is_security_scheme(dependant=dep)]
 
 
-@lru_cache(maxsize=1024)
+@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE)
 def _is_gen_callable_cached(call_identity: _CallIdentity) -> bool:
     call = call_identity.call
     if inspect.isgeneratorfunction(_impartial(call)) or inspect.isgeneratorfunction(
@@ -167,7 +168,7 @@ def _is_gen_callable(call: Callable[..., Any] | None) -> bool:
     return _is_gen_callable_cached(_CallIdentity(call))
 
 
-@lru_cache(maxsize=1024)
+@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE)
 def _is_async_gen_callable_cached(call_identity: _CallIdentity) -> bool:
     call = call_identity.call
     if inspect.isasyncgenfunction(_impartial(call)) or inspect.isasyncgenfunction(
@@ -197,7 +198,7 @@ def _is_async_gen_callable(call: Callable[..., Any] | None) -> bool:
     return _is_async_gen_callable_cached(_CallIdentity(call))
 
 
-@lru_cache(maxsize=1024)
+@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE)
 def _is_coroutine_callable_cached(call_identity: _CallIdentity) -> bool:
     call = call_identity.call
     if inspect.isroutine(_impartial(call)) and iscoroutinefunction(_impartial(call)):
index a2a36eaff4ecd2a8c2006b7e444e9ffbe1ef5b00..9ba6009442cb6b98b2541110bb94985279a84a4a 100644 (file)
@@ -1,4 +1,4 @@
-from collections.abc import AsyncGenerator, Generator
+from collections.abc import AsyncGenerator, Callable, Generator
 from typing import Any
 
 from fastapi.dependencies.models import (
@@ -93,7 +93,27 @@ def test_callable_classification_is_shared_by_call() -> None:
         cache_info = cached_function.cache_info()
         assert cache_info.hits == 1
         assert cache_info.misses == 1
-        assert cache_info.maxsize == 1024
+        assert cache_info.maxsize == 4096
+
+
+def test_callable_classification_cache_supports_large_apps() -> None:
+    callables: list[Callable[[], None]] = [lambda: None for _ in range(3000)]
+
+    for classifier, cached_classifier in (
+        (_is_gen_callable, _is_gen_callable_cached),
+        (_is_async_gen_callable, _is_async_gen_callable_cached),
+        (_is_coroutine_callable, _is_coroutine_callable_cached),
+    ):
+        cached_classifier.cache_clear()
+
+        for _ in range(2):
+            assert all(not classifier(call) for call in callables)
+
+        cache_info = cached_classifier.cache_info()
+        assert cache_info.hits == len(callables)
+        assert cache_info.misses == len(callables)
+        assert cache_info.maxsize == 4096
+        cached_classifier.cache_clear()
 
 
 def test_unhashable_callable_classification() -> None: