#29253 closed Bug (fixed)
method_decorator() with list argument doesn't copy over attributes of the decorator function
Reported by: | Chris Jerdonek | Owned by: | Chris Jerdonek |
---|---|---|---|
Component: | Utilities | Version: | 2.0 |
Severity: | Normal | Keywords: | decorators |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The docs say that the "list" form of @method_decorator
is equivalent to invoking it multiple times:
decorators = [never_cache, login_required] @method_decorator(decorators, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html' @method_decorator(never_cache, name='dispatch') @method_decorator(login_required, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html'
However, it appears there is a slight difference in behavior. For example:
from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt def my_decorator(func): def new_func(*args, **kwargs): func(*args, **kwargs) return new_func @method_decorator(my_decorator, name='dispatch') @method_decorator(csrf_exempt, name='dispatch') class View1: def dispatch(self): pass @method_decorator([my_decorator, csrf_exempt], name='dispatch') class View2: def dispatch(self): pass print(hasattr(View1.dispatch, 'csrf_exempt')) print(hasattr(View2.dispatch, 'csrf_exempt'))
results in the output--
True False
It appears this is because method_decorator()
takes a short cut when processing a list. It doesn't carry over the attributes of the decorated function like it does in the normal case.
Change History (8)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Summary: | method_decorator behaves differently with list argument → method_decorator() with list argument doesn't copy over attributes of the decorator function |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 7 years ago
Has patch: | set |
---|
I prepared a pull request here: https://github.com/django/django/pull/9819
comment:6 by , 6 years ago
PR 10091 fixes a regression where @method_decorator(transaction.non_atomic_requests)
crashes.
The behavior difference described in this ticket is actually noted in the discussion of the patch here, but it was thought not important. I do think it's important though because, for example, it can cause decorators to have or not have an effect depending on which invocation style is used.