From fd22244ad8156efe277bf13eb1727928b067aeed Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Sat, 19 Mar 2022 00:09:27 +0000 Subject: [PATCH] Added `detype_patterns()` with `@cache`. Avoids excessive calls to `detype_pattern()` with the same arguments. Co-authored-by: T. Franzel --- drf_spectacular/plumbing.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drf_spectacular/plumbing.py b/drf_spectacular/plumbing.py index 81e35f35..ace17cc8 100644 --- a/drf_spectacular/plumbing.py +++ b/drf_spectacular/plumbing.py @@ -891,7 +891,7 @@ def modify_for_versioning(patterns, method, path, view, requested_version): elif issubclass(view.versioning_class, versioning.NamespaceVersioning): try: view.request.resolver_match = get_resolver( - urlconf=tuple(detype_pattern(p) for p in patterns) + urlconf=detype_patterns(tuple(patterns)), ).resolve(path) except Resolver404: error(f"namespace versioning path resolution failed for {path}. Path will be ignored.") @@ -976,6 +976,12 @@ def analyze_named_regex_pattern(path): return result +@cache +def detype_patterns(patterns): + """Cache detyped patterns due to the expensive nature of rebuilding URLResolver.""" + return tuple(detype_pattern(pattern) for pattern in patterns) + + def detype_pattern(pattern): """ return an equivalent pattern that accepts arbitrary values for path parameters.