From 9642f1901805519b5eb512a2b55d9eb8a7251dc3 Mon Sep 17 00:00:00 2001 From: Mehdi Abaakouk Date: Mon, 20 Oct 2014 15:00:13 +0200 Subject: [PATCH] Fixes expose of staticmethod Since 9358e59af80d9c5f88d5713ca7d1e648bfad1403, we cannot expose staticmethod anymore because the pecan.util.getargspec is now looking for the content of __closure__ that is None is this case. This changes fixed that Change-Id: Iabba8310cc58e155c6aeefc481e118de84c58734 --- pecan/tests/test_util.py | 27 +++++++++++++++++++++++++++ pecan/util.py | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/pecan/tests/test_util.py b/pecan/tests/test_util.py index c1cdfbd..00e81f5 100644 --- a/pecan/tests/test_util.py +++ b/pecan/tests/test_util.py @@ -17,6 +17,11 @@ class TestArgSpec(unittest.TestCase): def index(self, a, b, c=1, *args, **kwargs): return 'Hello, World!' + @staticmethod + @expose() + def static_index(a, b, c=1, *args, **kwargs): + return 'Hello, World!' + return RootController() def test_no_decorator(self): @@ -24,6 +29,10 @@ class TestArgSpec(unittest.TestCase): actual = util.getargspec(self.controller.index.__func__) assert expected == actual + expected = inspect.getargspec(self.controller.static_index) + actual = util.getargspec(self.controller.static_index) + assert expected == actual + def test_simple_decorator(self): def dec(f): return f @@ -32,6 +41,10 @@ class TestArgSpec(unittest.TestCase): actual = util.getargspec(dec(self.controller.index.__func__)) assert expected == actual + expected = inspect.getargspec(self.controller.static_index) + actual = util.getargspec(dec(self.controller.static_index)) + assert expected == actual + def test_simple_wrapper(self): def dec(f): @functools.wraps(f) @@ -43,6 +56,10 @@ class TestArgSpec(unittest.TestCase): actual = util.getargspec(dec(self.controller.index.__func__)) assert expected == actual + expected = inspect.getargspec(self.controller.static_index) + actual = util.getargspec(dec(self.controller.static_index)) + assert expected == actual + def test_multiple_decorators(self): def dec(f): @functools.wraps(f) @@ -54,6 +71,11 @@ class TestArgSpec(unittest.TestCase): actual = util.getargspec(dec(dec(dec(self.controller.index.__func__)))) assert expected == actual + expected = inspect.getargspec(self.controller.static_index) + actual = util.getargspec(dec(dec(dec( + self.controller.static_index)))) + assert expected == actual + def test_decorator_with_args(self): def dec(flag): def inner(f): @@ -66,3 +88,8 @@ class TestArgSpec(unittest.TestCase): expected = inspect.getargspec(self.controller.index.__func__) actual = util.getargspec(dec(True)(self.controller.index.__func__)) assert expected == actual + + expected = inspect.getargspec(self.controller.static_index) + actual = util.getargspec(dec(True)( + self.controller.static_index)) + assert expected == actual diff --git a/pecan/util.py b/pecan/util.py index 168ff66..bdb5d2b 100644 --- a/pecan/util.py +++ b/pecan/util.py @@ -23,6 +23,12 @@ def getargspec(method): func_closure = six.get_function_closure(method) + # NOTE(sileht): if the closure is None we cannot look deeper, + # so return actual argspec, this occurs when the method + # is static for example. + if func_closure is None: + return argspec + closure = next( ( c for c in func_closure if six.callable(c.cell_contents)