Merge pull request #49 from ryanpetrello/origin/bug/47

Fix a bug in controller argspec detection when class-based decorators are used.
This commit is contained in:
Jonathan LaCour 2016-03-15 12:49:06 -07:00
commit 584e427de9
2 changed files with 28 additions and 2 deletions

View File

@ -113,3 +113,26 @@ class TestArgSpec(unittest.TestCase):
argspec = util._cfg(RootController.index)['argspec']
assert argspec.args == ['self', 'a', 'b', 'c']
def test_class_based_decorator(self):
class deco(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, f):
@functools.wraps(f)
def wrapper(*args, **kw):
assert self.arg == '12345'
return f(*args, **kw)
return wrapper
class RootController(object):
@expose()
@deco('12345')
def index(self, a, b, c):
return 'Hello, World!'
argspec = util._cfg(RootController.index)['argspec']
assert argspec.args == ['self', 'a', 'b', 'c']

View File

@ -33,9 +33,12 @@ def getargspec(method):
# In the case of deeply nested decorators (with arguments), it's possible
# that there are several callables in scope; Take a best guess and go
# with the one that looks most like a pecan controller function
# ('self' is the first argument)
# (has a __code__ object, and 'self' is the first argument)
func_closure = filter(
lambda c: six.callable(c.cell_contents),
lambda c: (
six.callable(c.cell_contents) and
hasattr(c.cell_contents, '__code__')
),
func_closure
)
func_closure = sorted(