Close #3610: autodoc: Support overloaded functions

This commit is contained in:
Takeshi KOMIYA 2020-05-24 23:34:09 +09:00
parent 640bb2e586
commit fb2f777079
4 changed files with 103 additions and 4 deletions

View File

@ -51,6 +51,7 @@ Features added
builtin base classes
* #2106: autodoc: Support multiple signatures on docstring
* #4422: autodoc: Support GenericAlias in Python 3.7 or above
* #3610: autodoc: Support overloaded functions
* #7466: autosummary: headings in generated documents are not translated
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
caption to the toctree

View File

@ -1192,8 +1192,14 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
self.add_line(' :async:', sourcename)
def format_signature(self, **kwargs: Any) -> str:
sig = super().format_signature(**kwargs)
sigs = [sig]
sigs = []
if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads:
# Use signatures for overloaded functions instead of the implementation function.
overloaded = True
else:
overloaded = False
sig = super().format_signature(**kwargs)
sigs.append(sig)
if inspect.is_singledispatch_function(self.object):
# append signature of singledispatch'ed functions
@ -1207,6 +1213,10 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
documenter.object = func
documenter.objpath = [None]
sigs.append(documenter.format_signature())
if overloaded:
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
sig = stringify_signature(overload, **kwargs)
sigs.append(sig)
return "\n".join(sigs)
@ -1693,8 +1703,14 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
pass
def format_signature(self, **kwargs: Any) -> str:
sig = super().format_signature(**kwargs)
sigs = [sig]
sigs = []
if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads:
# Use signatures for overloaded methods instead of the implementation method.
overloaded = True
else:
overloaded = False
sig = super().format_signature(**kwargs)
sigs.append(sig)
meth = self.parent.__dict__.get(self.objpath[-1])
if inspect.is_singledispatch_method(meth):
@ -1710,6 +1726,14 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
documenter.object = func
documenter.objpath = [None]
sigs.append(documenter.format_signature())
if overloaded:
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
if not inspect.isstaticmethod(self.object, cls=self.parent,
name=self.object_name):
parameters = list(overload.parameters.values())
overload = overload.replace(parameters=parameters[1:])
sig = stringify_signature(overload, **kwargs)
sigs.append(sig)
return "\n".join(sigs)

View File

@ -0,0 +1,41 @@
from typing import overload
@overload
def sum(x: int, y: int) -> int:
...
@overload
def sum(x: float, y: float) -> float:
...
@overload
def sum(x: str, y: str) -> str:
...
def sum(x, y):
"""docstring"""
return x + y
class Math:
"""docstring"""
@overload
def sum(self, x: int, y: int) -> int:
...
@overload
def sum(self, x: float, y: float) -> float:
...
@overload
def sum(self, x: str, y: str) -> str:
...
def sum(self, x, y):
"""docstring"""
return x + y

View File

@ -1787,6 +1787,39 @@ def test_final(app):
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_overload(app):
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.overload', options)
assert list(actual) == [
'',
'.. py:module:: target.overload',
'',
'',
'.. py:class:: Math()',
' :module: target.overload',
'',
' docstring',
'',
'',
' .. py:method:: Math.sum(x: int, y: int) -> int',
' Math.sum(x: float, y: float) -> float',
' Math.sum(x: str, y: str) -> str',
' :module: target.overload',
'',
' docstring',
'',
'',
'.. py:function:: sum(x: int, y: int) -> int',
' sum(x: float, y: float) -> float',
' sum(x: str, y: str) -> str',
' :module: target.overload',
'',
' docstring',
'',
]
@pytest.mark.sphinx('dummy', testroot='ext-autodoc')
def test_autodoc(app, status, warning):
app.builder.build_all()