From 4dcc35a6490d3d00fa2eb8313e75ac0bd80ec109 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 17 Jun 2017 00:42:21 +0900 Subject: [PATCH] Signature formats args of method correctly in py2 --- sphinx/util/inspect.py | 13 ++++++++++++- tests/test_util_inspect.py | 39 +++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index eb6e2eab1..e568131b7 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -275,6 +275,13 @@ class Signature(object): except: self.annotations = None + if PY3: + # inspect.signature recognizes bound methods automatically + self.skip_first_argument = False + else: + # check subject is bound method or not to skip first argument (ex. self) + self.skip_first_argument = inspect.ismethod(subject) and subject.__self__ + @property def parameters(self): # type: () -> Dict @@ -309,7 +316,11 @@ class Signature(object): # type: () -> unicode args = [] last_kind = None - for param in itervalues(self.parameters): + for i, param in enumerate(itervalues(self.parameters)): + # skip first argument if subject is bound method + if self.skip_first_argument and i == 0: + continue + arg = StringIO() # insert '*' between POSITIONAL args and KEYWORD_ONLY args:: diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index 02164414c..dcdb186a6 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -148,27 +148,44 @@ def test_Signature_partial(): assert sig == '(b, *, c=11, d=2)' -def test_Signature_bound_methods(): +def test_Signature_methods(): class Foo: - def method(self, arg1, **kwargs): + def meth1(self, arg1, **kwargs): pass - bound_method = Foo().method + @classmethod + def meth2(cls, arg1, *args, **kwargs): + pass - @functools.wraps(bound_method) + @staticmethod + def meth3(arg1, *args, **kwargs): + pass + + @functools.wraps(Foo().meth1) def wrapped_bound_method(*args, **kwargs): pass - # class method - sig = inspect.Signature(Foo.method).format_args() + # unbound method + sig = inspect.Signature(Foo.meth1).format_args() assert sig == '(self, arg1, **kwargs)' # bound method - sig = inspect.Signature(bound_method).format_args() - if sys.version_info < (3, 4, 4): - assert sig == '(self, arg1, **kwargs)' - else: - assert sig == '(arg1, **kwargs)' + sig = inspect.Signature(Foo().meth1).format_args() + assert sig == '(arg1, **kwargs)' + + # class method + sig = inspect.Signature(Foo.meth2).format_args() + assert sig == '(arg1, *args, **kwargs)' + + sig = inspect.Signature(Foo().meth2).format_args() + assert sig == '(arg1, *args, **kwargs)' + + # static method + sig = inspect.Signature(Foo.meth3).format_args() + assert sig == '(arg1, *args, **kwargs)' + + sig = inspect.Signature(Foo().meth3).format_args() + assert sig == '(arg1, *args, **kwargs)' # wrapped bound method sig = inspect.Signature(wrapped_bound_method).format_args()