Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #21247 -- Made method_decorator play nicely with descriptors

When a method decorator was used in conjunction with a decorator
implemented as a descriptor, method_decorator did not correctly respect
the method binding.

Thanks for Graham Dumpleton for the report and initial patch.
  • Loading branch information...
commit 80cd64ee17191ffb235c5850a8fa60cae96c1b89 1 parent 97a8fd4
@mjtamlyn mjtamlyn authored
Showing with 38 additions and 2 deletions.
  1. +1 −1  django/utils/decorators.py
  2. +37 −1 tests/decorators/tests.py
View
2  django/utils/decorators.py
@@ -22,7 +22,7 @@ def _dec(func):
def _wrapper(self, *args, **kwargs):
@decorator
def bound_func(*args2, **kwargs2):
- return func(self, *args2, **kwargs2)
+ return func.__get__(self, type(self))(*args2, **kwargs2)
# bound_func has the signature that 'decorator' expects i.e. no
# 'self' argument, but it is a closure over self so it can call
# 'func' correctly.
View
38 tests/decorators/tests.py
@@ -232,9 +232,45 @@ class Test(object):
def method(self):
return True
- # t = Test()
self.assertEqual(Test().method(), False)
+ def test_descriptors(self):
+
+ def original_dec(wrapped):
+ def _wrapped(arg):
+ return wrapped(arg)
+
+ return _wrapped
+
+ method_dec = method_decorator(original_dec)
+
+ class bound_wrapper(object):
+ def __init__(self, wrapped):
+ self.wrapped = wrapped
+ self.__name__ = wrapped.__name__
+
+ def __call__(self, arg):
+ return self.wrapped(arg)
+
+ def __get__(self, instance, owner):
+ return self
+
+ class descriptor_wrapper(object):
+ def __init__(self, wrapped):
+ self.wrapped = wrapped
+ self.__name__ = wrapped.__name__
+
+ def __get__(self, instance, owner):
+ return bound_wrapper(self.wrapped.__get__(instance, owner))
+
+ class Test(object):
+ @method_dec
+ @descriptor_wrapper
+ def method(self, arg):
+ return arg
+
+ self.assertEqual(Test().method(1), 1)
+
class XFrameOptionsDecoratorsTests(TestCase):
"""
Please sign in to comment.
Something went wrong with that request. Please try again.