Kaydet (Commit) 80cd64ee authored tarafından Marc Tamlyn's avatar Marc Tamlyn

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.
üst 97a8fd46
...@@ -22,7 +22,7 @@ def method_decorator(decorator): ...@@ -22,7 +22,7 @@ def method_decorator(decorator):
def _wrapper(self, *args, **kwargs): def _wrapper(self, *args, **kwargs):
@decorator @decorator
def bound_func(*args2, **kwargs2): 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 # bound_func has the signature that 'decorator' expects i.e. no
# 'self' argument, but it is a closure over self so it can call # 'self' argument, but it is a closure over self so it can call
# 'func' correctly. # 'func' correctly.
......
...@@ -232,9 +232,45 @@ class MethodDecoratorTests(TestCase): ...@@ -232,9 +232,45 @@ class MethodDecoratorTests(TestCase):
def method(self): def method(self):
return True return True
# t = Test()
self.assertEqual(Test().method(), False) 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): class XFrameOptionsDecoratorsTests(TestCase):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment