Fixed #21513 -- Added method_decorator support for argumented decorator

Copied attributes into the decorated method and special case __name__
copy as this will not be present on a Class object. Added regression
test to decorator suite.
This commit is contained in:
dpwrussell 2013-11-26 12:00:50 +00:00
parent 16d73d7416
commit 14940fdd96
2 changed files with 27 additions and 3 deletions

View File

@ -39,9 +39,13 @@ def method_decorator(decorator):
update_wrapper(_wrapper, func)
return _wrapper
update_wrapper(_dec, decorator)
update_wrapper(_dec, decorator, assigned=available_attrs(decorator))
# Change the name to aid debugging.
_dec.__name__ = 'method_decorator(%s)' % decorator.__name__
if hasattr(decorator, '__name__'):
_dec.__name__ = 'method_decorator(%s)' % decorator.__name__
else:
_dec.__name__ = 'method_decorator(%s)' % decorator.__class__.__name__
return _dec

View File

@ -1,4 +1,4 @@
from functools import wraps
from functools import wraps, update_wrapper
from unittest import TestCase
import warnings
@ -174,6 +174,16 @@ def myattr2_dec(func):
myattr2_dec_m = method_decorator(myattr2_dec)
class ClsDec(object):
def __init__(self, myattr):
self.myattr = myattr
def __call__(self, f):
def wrapped():
return f() and self.myattr
return update_wrapper(wrapped, f)
class MethodDecoratorTests(TestCase):
"""
@ -214,6 +224,16 @@ class MethodDecoratorTests(TestCase):
self.assertEqual(Test.method.__doc__, 'A method')
self.assertEqual(Test.method.__name__, 'method')
# Test for argumented decorator
def test_argumented(self):
class Test(object):
@method_decorator(ClsDec(False))
def method(self):
return True
# t = Test()
self.assertEqual(Test().method(), False)
class XFrameOptionsDecoratorsTests(TestCase):
"""