summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Iles <aaron.iles+github@gmail.com>2013-10-16 03:58:20 -0700
committerAaron Iles <aaron.iles+github@gmail.com>2013-10-16 03:58:20 -0700
commit769506ea748a38d03de2f2953af291aa40216684 (patch)
treed62d0b3b4a24587cd6cecd770d6d49af0cf8fba0
parent59ab8ac5ea71d5b5163be0b12d5447969b252c43 (diff)
parent50d63cb7c57677d25b2b621f36ab6677c8876251 (diff)
downloadfuncsigs-769506ea748a38d03de2f2953af291aa40216684.tar.gz
Merge pull request #3 from epsy/unbound
Fixed unbound methods getting their first parameter curried Ensures the the 'self' argument of methods on un-instantiated classes appear in the function signature on both Python2 and Python3. Also ensures self is identified correctly as a positional-only parameter.
-rw-r--r--funcsigs/__init__.py16
-rw-r--r--tests/test_funcsigs.py18
2 files changed, 31 insertions, 3 deletions
diff --git a/funcsigs/__init__.py b/funcsigs/__init__.py
index b9ba326..fd2f47b 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=(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..eecc0a8 100644
--- a/tests/test_funcsigs.py
+++ b/tests/test_funcsigs.py
@@ -6,6 +6,7 @@ except ImportError:
import unittest
import doctest
+import sys
import funcsigs as inspect
@@ -70,6 +71,23 @@ class TestFunctionSignatures(unittest.TestCase):
def test_readme(self):
doctest.testfile('../README.rst')
+ def test_unbound_method(self):
+ if sys.version_info < (3,):
+ self_kind = "positional_only"
+ else:
+ self_kind = "positional_or_keyword"
+ class Test(object):
+ def method(self):
+ pass
+ def method_with_args(self, a):
+ pass
+ self.assertEqual(self.signature(Test.method),
+ (((('self', Ellipsis, Ellipsis, self_kind)),), Ellipsis))
+ self.assertEqual(self.signature(Test.method_with_args), ((
+ ('self', Ellipsis, Ellipsis, self_kind),
+ ('a', Ellipsis, Ellipsis, "positional_or_keyword"),
+ ), Ellipsis))
+
if __name__ == "__main__":
unittest.begin()