aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Kaiser <kaiser.yann@gmail.com>2013-10-14 02:50:04 +0100
committerYann Kaiser <kaiser.yann@gmail.com>2013-10-14 02:50:04 +0100
commite9822685f7d0f653e49b639b1b88cd196cf5fd48 (patch)
treedd7a10fd55e5b119c9744f9f7a893b99a22425cc
parent59ab8ac5ea71d5b5163be0b12d5447969b252c43 (diff)
downloadplatform_external_python_funcsigs-e9822685f7d0f653e49b639b1b88cd196cf5fd48.tar.gz
platform_external_python_funcsigs-e9822685f7d0f653e49b639b1b88cd196cf5fd48.tar.bz2
platform_external_python_funcsigs-e9822685f7d0f653e49b639b1b88cd196cf5fd48.zip
Fixed unbound methods getting their first parameter curried
-rw-r--r--funcsigs/__init__.py16
-rw-r--r--tests/test_funcsigs.py13
2 files changed, 26 insertions, 3 deletions
diff --git a/funcsigs/__init__.py b/funcsigs/__init__.py
index b9ba326..7dbe0dc 100644
--- a/funcsigs/__init__.py
+++ b/funcsigs/__init__.py
@@ -59,10 +59,20 @@ def signature(obj):
raise TypeError('{0!r} is not a callable object'.format(obj))
if isinstance(obj, types.MethodType):
- # In this case we skip the first parameter of the underlying
- # function (usually `self` or `cls`).
sig = signature(obj.__func__)
- return sig.replace(parameters=tuple(sig.parameters.values())[1:])
+ if obj.__self__ is None:
+ # Unbound method: the first parameter becomes positional-only
+ if sig.parameters:
+ first = sig.parameters.values()[0].replace(
+ kind=_POSITIONAL_ONLY)
+ return sig.replace(parameters=itertools.chain(
+ (first,), tuple(sig.parameters.values())[1:]))
+ else:
+ return sig
+ else:
+ # In this case we skip the first parameter of the underlying
+ # function (usually `self` or `cls`).
+ return sig.replace(parameters=tuple(sig.parameters.values())[1:])
try:
sig = obj.__signature__
diff --git a/tests/test_funcsigs.py b/tests/test_funcsigs.py
index c904caf..227131f 100644
--- a/tests/test_funcsigs.py
+++ b/tests/test_funcsigs.py
@@ -70,6 +70,19 @@ class TestFunctionSignatures(unittest.TestCase):
def test_readme(self):
doctest.testfile('../README.rst')
+ def test_unbound_method(self):
+ class Test(object):
+ def method(self):
+ pass
+ def method_with_args(self, a):
+ pass
+ self.assertEqual(self.signature(Test.method),
+ (((('self', Ellipsis, Ellipsis, "positional_only")),), Ellipsis))
+ self.assertEqual(self.signature(Test.method_with_args), ((
+ ('self', Ellipsis, Ellipsis, "positional_only"),
+ ('a', Ellipsis, Ellipsis, "positional_or_keyword"),
+ ), Ellipsis))
+
if __name__ == "__main__":
unittest.begin()