From a8f68a382feec98990df1c7d5e6df5cfb53bd27e Mon Sep 17 00:00:00 2001 From: ipeluffo Date: Tue, 14 Apr 2026 11:04:30 +0100 Subject: [PATCH] Refactor `Dependant._is_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 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/fastapi/dependencies/models.py b/fastapi/dependencies/models.py index 9bfff02a77..d0791fbce7 100644 --- a/fastapi/dependencies/models.py +++ b/fastapi/dependencies/models.py @@ -53,6 +53,7 @@ class Dependant: _oauth_scopes_cache: list[str] = field(default=None, init=False, repr=False) _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) @property def oauth_scopes(self) -> list[str]: @@ -97,15 +98,19 @@ class Dependant: if self._uses_scopes_cache is None: self._uses_scopes_cache = False - + return self._uses_scopes_cache - @cached_property + @property def _is_security_scheme(self) -> bool: - if self.call is None: - return False # pragma: no cover - unwrapped = _unwrapped_call(self.call) - return isinstance(unwrapped, SecurityBase) + if self._is_security_scheme_cache is None: + if self.call is None: + self._is_security_scheme_cache = False # pragma: no cover + else: + unwrapped = _unwrapped_call(self.call) + self._is_security_scheme_cache = isinstance(unwrapped, SecurityBase) + + return self._is_security_scheme_cache # Mainly to get the type of SecurityBase, but it's the same self.call @cached_property