diff options
author | Aaron Iles <aaron.iles+github@gmail.com> | 2013-10-16 03:58:20 -0700 |
---|---|---|
committer | Aaron Iles <aaron.iles+github@gmail.com> | 2013-10-16 03:58:20 -0700 |
commit | 769506ea748a38d03de2f2953af291aa40216684 (patch) | |
tree | d62d0b3b4a24587cd6cecd770d6d49af0cf8fba0 | |
parent | 59ab8ac5ea71d5b5163be0b12d5447969b252c43 (diff) | |
parent | 50d63cb7c57677d25b2b621f36ab6677c8876251 (diff) | |
download | funcsigs-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__.py | 16 | ||||
-rw-r--r-- | tests/test_funcsigs.py | 18 |
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() |