Fix #4539: autodoc emits warnings for partialmethods

This commit is contained in:
Takeshi KOMIYA 2018-02-03 12:01:52 +09:00
parent 39d4584248
commit 758e051ed2
5 changed files with 107 additions and 3 deletions

View File

@ -17,6 +17,7 @@ Bugs fixed
----------
* #4019: inheritance_diagram AttributeError stoping make process
* #4539: autodoc emits warnings for partialmethods
Testing
--------

View File

@ -307,9 +307,17 @@ class Signature(object):
raise TypeError("can't compute signature for built-in type {}".format(subject))
self.subject = subject
self.partialmethod_with_noargs = False
if PY3:
self.signature = inspect.signature(subject)
try:
self.signature = inspect.signature(subject)
except IndexError:
if hasattr(subject, '_partialmethod'): # partialmethod with no argument
self.signature = None
self.partialmethod_with_noargs = True
else:
raise
else:
self.argspec = getargspec(subject)
@ -339,7 +347,10 @@ class Signature(object):
def parameters(self):
# type: () -> Dict
if PY3:
return self.signature.parameters
if self.partialmethod_with_noargs:
return {}
else:
return self.signature.parameters
else:
params = OrderedDict() # type: Dict
positionals = len(self.argspec.args) - len(self.argspec.defaults)
@ -360,7 +371,7 @@ class Signature(object):
@property
def return_annotation(self):
# type: () -> Any
if PY3:
if PY3 and self.signature:
return self.signature.return_annotation
else:
return None

View File

@ -0,0 +1,18 @@
# for py34 or above
from functools import partialmethod
class Cell(object):
"""An example for partialmethod.
refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod
"""
def set_state(self, state):
"""Update state of cell to *state*."""
#: Make a cell alive.
set_alive = partialmethod(set_state, True)
set_dead = partialmethod(set_state, False)
"""Make a cell dead."""

View File

@ -907,3 +907,50 @@ def test_generate():
options.members = ['decoratedFunction']
assert_result_contains('.. py:function:: decoratedFunction()',
'module', 'autodoc_missing_imports')
@pytest.mark.skipif(sys.version_info < (3, 4),
reason='functools.partialmethod is available on py34 or above')
@pytest.mark.usefixtures('setup_test')
def test_partialmethod():
def call_autodoc(objtype, name):
inst = app.registry.documenters[objtype](directive, name)
inst.generate()
result = list(directive.result)
del directive.result[:]
return result
options.inherited_members = True
options.undoc_members = True
expected = [
'',
'.. py:class:: Cell',
' :module: target.partialmethod',
'',
' An example for partialmethod.',
' ',
' refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod',
' ',
' ',
' .. py:method:: Cell.set_alive() -> None',
' :module: target.partialmethod',
' ',
' Make a cell alive.',
' ',
' ',
' .. py:method:: Cell.set_dead() -> None',
' :module: target.partialmethod',
' ',
' Make a cell dead.',
' ',
' ',
' .. py:method:: Cell.set_state(state)',
' :module: target.partialmethod',
' ',
' Update state of cell to *state*.',
' ',
]
if sys.version_info < (3, 5):
expected = '\n'.join(expected).replace(' -> None', '').split('\n')
assert call_autodoc('class', 'target.partialmethod.Cell') == expected

View File

@ -200,6 +200,33 @@ def test_Signature_methods():
assert sig == '(arg1, **kwargs)'
@pytest.mark.skipif(sys.version_info < (3, 4),
reason='functools.partialmethod is available on py34 or above')
def test_Signature_partialmethod():
from functools import partialmethod
class Foo(object):
def meth1(self, arg1, arg2, arg3=None, arg4=None):
pass
def meth2(self, arg1, arg2):
pass
foo = partialmethod(meth1, 1, 2)
bar = partialmethod(meth1, 1, arg3=3)
baz = partialmethod(meth2, 1, 2)
subject = Foo()
sig = inspect.Signature(subject.foo).format_args()
assert sig == '(arg3=None, arg4=None)'
sig = inspect.Signature(subject.bar).format_args()
assert sig == '(arg2, *, arg3=3, arg4=None)'
sig = inspect.Signature(subject.baz).format_args()
assert sig == '()'
@pytest.mark.skipif(sys.version_info < (3, 5),
reason='type annotation test is available on py35 or above')
def test_Signature_annotations():