From b5b53afa29c53a79ae92ed5298144db0cab0ea3b Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 11 Jun 2026 23:37:13 +0200 Subject: Refs #36532 -- Optimized CSP decorator async checking. The previous approach created both sync and async wrappers before checking which one was needed. Checking first reduces about 1 microsecond off each decorator application. --- django/views/decorators/csp.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/django/views/decorators/csp.py b/django/views/decorators/csp.py index 1c537fe1f2..c6ee54fea4 100644 --- a/django/views/decorators/csp.py +++ b/django/views/decorators/csp.py @@ -9,11 +9,15 @@ def _make_csp_decorator(config_attr_name, config_attr_value): raise TypeError("CSP config should be a mapping.") def decorator(view_func): - @wraps(view_func) - async def _wrapped_async_view(request, *args, **kwargs): - response = await view_func(request, *args, **kwargs) - setattr(response, config_attr_name, config_attr_value) - return response + if iscoroutinefunction(view_func): + + @wraps(view_func) + async def _wrapped_async_view(request, *args, **kwargs): + response = await view_func(request, *args, **kwargs) + setattr(response, config_attr_name, config_attr_value) + return response + + return _wrapped_async_view @wraps(view_func) def _wrapped_sync_view(request, *args, **kwargs): @@ -21,8 +25,6 @@ def _make_csp_decorator(config_attr_name, config_attr_value): setattr(response, config_attr_name, config_attr_value) return response - if iscoroutinefunction(view_func): - return _wrapped_async_view return _wrapped_sync_view return decorator -- cgit v1.3