From b89e501c7513101eb56d065943369822652b7a85 Mon Sep 17 00:00:00 2001 From: ipeluffo Date: Tue, 14 Apr 2026 11:06:52 +0100 Subject: [PATCH] Refactor `Dependant._security_scheme` property for improved memory usage ``` Samples: 200000 - current=318.4 MB peak=318.4 MB Samples: 100000 - current=159.2 MB peak=159.2 MB Samples: 50000 - current=79.6 MB peak=79.6 MB Samples: 1000 - current=1.6 MB peak=1.6 MB Samples: 500 - current=0.8 MB peak=0.8 MB ``` --- fastapi/dependencies/models.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fastapi/dependencies/models.py b/fastapi/dependencies/models.py index d0791fbce7..d325ceeb1a 100644 --- a/fastapi/dependencies/models.py +++ b/fastapi/dependencies/models.py @@ -54,6 +54,7 @@ class Dependant: _cache_key_cache: DependencyCacheKey = field(default=None, init=False, repr=False) _uses_scopes_cache: bool = field(default=None, init=False, repr=False) _is_security_scheme_cache: bool = field(default=False, init=False, repr=False) + _security_scheme_cache: SecurityBase = field(default=None, init=False, repr=False) @property def oauth_scopes(self) -> list[str]: @@ -113,11 +114,14 @@ class Dependant: return self._is_security_scheme_cache # Mainly to get the type of SecurityBase, but it's the same self.call - @cached_property + @property def _security_scheme(self) -> SecurityBase: - unwrapped = _unwrapped_call(self.call) - assert isinstance(unwrapped, SecurityBase) - return unwrapped + if self._security_scheme_cache is None: + unwrapped = _unwrapped_call(self.call) + assert isinstance(unwrapped, SecurityBase) + self._security_scheme_cache = unwrapped + + return self._security_scheme_cache @cached_property def _security_dependencies(self) -> list["Dependant"]: