Files
deb-python-pecan/pecan/tests/test_util.py
Ryan Petrello 9358e59af8 Improve argspec detection and leniency for wrapped controllers.
Pecan makes abundant use of `inspect.getargspec`, but unless you're very
meticulous in the decorators you wrap your controllers with, the original
argspec is not persisted (and pecan functionality can break in various ways).
When a controller is decorated in a way that breaks argspec, we should instead
attempt to locate the *actual* argspec for the method (not the wrapped
function) and use it.

Additionally, when controllers are missing **kwargs in the method signature to
map optional GET and POST arguments, we shouldn't consider that
a non-routable offense (an HTTP 400); instead, we should just *not* pass
extraneous arguments to the function.

Change-Id: I47fe0496ff6aa105359ee8e5b99f6c80476cc2e9
2014-09-24 18:00:08 -04:00

69 lines
2.0 KiB
Python

import functools
import inspect
import unittest
from pecan import expose
from pecan import util
class TestArgSpec(unittest.TestCase):
@property
def controller(self):
class RootController(object):
@expose()
def index(self, a, b, c=1, *args, **kwargs):
return 'Hello, World!'
return RootController()
def test_no_decorator(self):
expected = inspect.getargspec(self.controller.index.__func__)
actual = util.getargspec(self.controller.index.__func__)
assert expected == actual
def test_simple_decorator(self):
def dec(f):
return f
expected = inspect.getargspec(self.controller.index.__func__)
actual = util.getargspec(dec(self.controller.index.__func__))
assert expected == actual
def test_simple_wrapper(self):
def dec(f):
@functools.wraps(f)
def wrapped(*a, **kw):
return f(*a, **kw)
return wrapped
expected = inspect.getargspec(self.controller.index.__func__)
actual = util.getargspec(dec(self.controller.index.__func__))
assert expected == actual
def test_multiple_decorators(self):
def dec(f):
@functools.wraps(f)
def wrapped(*a, **kw):
return f(*a, **kw)
return wrapped
expected = inspect.getargspec(self.controller.index.__func__)
actual = util.getargspec(dec(dec(dec(self.controller.index.__func__))))
assert expected == actual
def test_decorator_with_args(self):
def dec(flag):
def inner(f):
@functools.wraps(f)
def wrapped(*a, **kw):
return f(*a, **kw)
return wrapped
return inner
expected = inspect.getargspec(self.controller.index.__func__)
actual = util.getargspec(dec(True)(self.controller.index.__func__))
assert expected == actual