From 9e6e32bf5dce69f3257fcbe4ce80839fb65ab3df Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 21 Jan 2017 13:20:17 -0500 Subject: [PATCH] Refs #23919 -- Removed django.utils.decorators.available_attrs() usage. It's only needed to workaround a bug on Python 2. --- django/contrib/auth/decorators.py | 3 +-- django/core/handlers/exception.py | 3 +-- django/test/utils.py | 3 +-- django/utils/decorators.py | 5 +++-- django/views/decorators/cache.py | 8 +++----- django/views/decorators/clickjacking.py | 8 +++----- django/views/decorators/csrf.py | 4 ++-- django/views/decorators/http.py | 6 +++--- django/views/decorators/vary.py | 5 ++--- 9 files changed, 19 insertions(+), 26 deletions(-) diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 807ea8a3f6..55a23ade56 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -5,7 +5,6 @@ from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url -from django.utils.decorators import available_attrs def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): @@ -16,7 +15,7 @@ def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIE """ def decorator(view_func): - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py index 5e489f64d3..febe5d8c87 100644 --- a/django/core/handlers/exception.py +++ b/django/core/handlers/exception.py @@ -8,7 +8,6 @@ from django.core.exceptions import PermissionDenied, SuspiciousOperation from django.http import Http404 from django.http.multipartparser import MultiPartParserError from django.urls import get_resolver, get_urlconf -from django.utils.decorators import available_attrs from django.utils.encoding import force_text from django.views import debug @@ -28,7 +27,7 @@ def convert_exception_to_response(get_response): no middleware leaks an exception and that the next middleware in the stack can rely on getting a response instead of an exception. """ - @wraps(get_response, assigned=available_attrs(get_response)) + @wraps(get_response) def inner(request): try: response = get_response(request) diff --git a/django/test/utils.py b/django/test/utils.py index a587e1fa96..2bd6bb4d0f 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -22,7 +22,6 @@ from django.db.models.options import Options from django.template import Template from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix -from django.utils.decorators import available_attrs from django.utils.translation import deactivate try: @@ -370,7 +369,7 @@ class TestContextDecorator: raise TypeError('Can only decorate subclasses of unittest.TestCase') def decorate_callable(self, func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(*args, **kwargs): with self as context: if self.kwarg_name: diff --git a/django/utils/decorators.py b/django/utils/decorators.py index a3af946b33..7621d2fabd 100644 --- a/django/utils/decorators.py +++ b/django/utils/decorators.py @@ -79,7 +79,7 @@ def method_decorator(decorator, name=''): # Don't worry about making _dec look similar to a list/tuple as it's rather # meaningless. if not hasattr(decorator, '__iter__'): - update_wrapper(_dec, decorator, assigned=available_attrs(decorator)) + update_wrapper(_dec, decorator) # Change the name to aid debugging. if hasattr(decorator, '__name__'): _dec.__name__ = 'method_decorator(%s)' % decorator.__name__ @@ -113,6 +113,7 @@ def decorator_from_middleware(middleware_class): return make_middleware_decorator(middleware_class)() +# Unused, for backwards compatibility in Django 2.0. def available_attrs(fn): """ Return the list of functools-wrappable attributes on a callable. @@ -127,7 +128,7 @@ def make_middleware_decorator(middleware_class): middleware = middleware_class(*m_args, **m_kwargs) def _decorator(view_func): - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if hasattr(middleware, 'process_request'): result = middleware.process_request(request) diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index 07e0e70946..18238aaae7 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -2,9 +2,7 @@ from functools import wraps from django.middleware.cache import CacheMiddleware from django.utils.cache import add_never_cache_headers, patch_cache_control -from django.utils.decorators import ( - available_attrs, decorator_from_middleware_with_args, -) +from django.utils.decorators import decorator_from_middleware_with_args def cache_page(*args, **kwargs): @@ -38,7 +36,7 @@ def cache_page(*args, **kwargs): def cache_control(**kwargs): def _cache_controller(viewfunc): - @wraps(viewfunc, assigned=available_attrs(viewfunc)) + @wraps(viewfunc) def _cache_controlled(request, *args, **kw): response = viewfunc(request, *args, **kw) patch_cache_control(response, **kwargs) @@ -52,7 +50,7 @@ def never_cache(view_func): Decorator that adds headers to a response so that it will never be cached. """ - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view_func(request, *args, **kwargs): response = view_func(request, *args, **kwargs) add_never_cache_headers(response) diff --git a/django/views/decorators/clickjacking.py b/django/views/decorators/clickjacking.py index bb63c50096..828ae3c1fd 100644 --- a/django/views/decorators/clickjacking.py +++ b/django/views/decorators/clickjacking.py @@ -1,7 +1,5 @@ from functools import wraps -from django.utils.decorators import available_attrs - def xframe_options_deny(view_func): """ @@ -20,7 +18,7 @@ def xframe_options_deny(view_func): if resp.get('X-Frame-Options') is None: resp['X-Frame-Options'] = 'DENY' return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) def xframe_options_sameorigin(view_func): @@ -40,7 +38,7 @@ def xframe_options_sameorigin(view_func): if resp.get('X-Frame-Options') is None: resp['X-Frame-Options'] = 'SAMEORIGIN' return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) def xframe_options_exempt(view_func): @@ -58,4 +56,4 @@ def xframe_options_exempt(view_func): resp = view_func(*args, **kwargs) resp.xframe_options_exempt = True return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) diff --git a/django/views/decorators/csrf.py b/django/views/decorators/csrf.py index d8c89c176c..d5ff6da90e 100644 --- a/django/views/decorators/csrf.py +++ b/django/views/decorators/csrf.py @@ -1,7 +1,7 @@ from functools import wraps from django.middleware.csrf import CsrfViewMiddleware, get_token -from django.utils.decorators import available_attrs, decorator_from_middleware +from django.utils.decorators import decorator_from_middleware csrf_protect = decorator_from_middleware(CsrfViewMiddleware) csrf_protect.__name__ = "csrf_protect" @@ -57,4 +57,4 @@ def csrf_exempt(view_func): def wrapped_view(*args, **kwargs): return view_func(*args, **kwargs) wrapped_view.csrf_exempt = True - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) diff --git a/django/views/decorators/http.py b/django/views/decorators/http.py index 21b56a3202..f0eeeb0005 100644 --- a/django/views/decorators/http.py +++ b/django/views/decorators/http.py @@ -9,7 +9,7 @@ from functools import wraps from django.http import HttpResponseNotAllowed from django.middleware.http import ConditionalGetMiddleware from django.utils.cache import get_conditional_response -from django.utils.decorators import available_attrs, decorator_from_middleware +from django.utils.decorators import decorator_from_middleware from django.utils.http import http_date, quote_etag conditional_page = decorator_from_middleware(ConditionalGetMiddleware) @@ -29,7 +29,7 @@ def require_http_methods(request_method_list): Note that request methods should be in uppercase. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(request, *args, **kwargs): if request.method not in request_method_list: logger.warning( @@ -75,7 +75,7 @@ def condition(etag_func=None, last_modified_func=None): already have them. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): diff --git a/django/views/decorators/vary.py b/django/views/decorators/vary.py index df92c65c5c..68b783ed3a 100644 --- a/django/views/decorators/vary.py +++ b/django/views/decorators/vary.py @@ -1,7 +1,6 @@ from functools import wraps from django.utils.cache import patch_vary_headers -from django.utils.decorators import available_attrs def vary_on_headers(*headers): @@ -16,7 +15,7 @@ def vary_on_headers(*headers): Note that the header names are not case-sensitive. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner_func(*args, **kwargs): response = func(*args, **kwargs) patch_vary_headers(response, headers) @@ -34,7 +33,7 @@ def vary_on_cookie(func): def index(request): ... """ - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner_func(*args, **kwargs): response = func(*args, **kwargs) patch_vary_headers(response, ('Cookie',))