Skip to content

Commit fb2f777

Browse files
committed
Close #3610: autodoc: Support overloaded functions
1 parent 640bb2e commit fb2f777

File tree

4 files changed

+103
-4
lines changed

4 files changed

+103
-4
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Features added
5151
builtin base classes
5252
* #2106: autodoc: Support multiple signatures on docstring
5353
* #4422: autodoc: Support GenericAlias in Python 3.7 or above
54+
* #3610: autodoc: Support overloaded functions
5455
* #7466: autosummary: headings in generated documents are not translated
5556
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
5657
caption to the toctree

sphinx/ext/autodoc/__init__.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,8 +1192,14 @@ def add_directive_header(self, sig: str) -> None:
11921192
self.add_line(' :async:', sourcename)
11931193

11941194
def format_signature(self, **kwargs: Any) -> str:
1195-
sig = super().format_signature(**kwargs)
1196-
sigs = [sig]
1195+
sigs = []
1196+
if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads:
1197+
# Use signatures for overloaded functions instead of the implementation function.
1198+
overloaded = True
1199+
else:
1200+
overloaded = False
1201+
sig = super().format_signature(**kwargs)
1202+
sigs.append(sig)
11971203

11981204
if inspect.is_singledispatch_function(self.object):
11991205
# append signature of singledispatch'ed functions
@@ -1207,6 +1213,10 @@ def format_signature(self, **kwargs: Any) -> str:
12071213
documenter.object = func
12081214
documenter.objpath = [None]
12091215
sigs.append(documenter.format_signature())
1216+
if overloaded:
1217+
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
1218+
sig = stringify_signature(overload, **kwargs)
1219+
sigs.append(sig)
12101220

12111221
return "\n".join(sigs)
12121222

@@ -1693,8 +1703,14 @@ def document_members(self, all_members: bool = False) -> None:
16931703
pass
16941704

16951705
def format_signature(self, **kwargs: Any) -> str:
1696-
sig = super().format_signature(**kwargs)
1697-
sigs = [sig]
1706+
sigs = []
1707+
if self.analyzer and '.'.join(self.objpath) in self.analyzer.overloads:
1708+
# Use signatures for overloaded methods instead of the implementation method.
1709+
overloaded = True
1710+
else:
1711+
overloaded = False
1712+
sig = super().format_signature(**kwargs)
1713+
sigs.append(sig)
16981714

16991715
meth = self.parent.__dict__.get(self.objpath[-1])
17001716
if inspect.is_singledispatch_method(meth):
@@ -1710,6 +1726,14 @@ def format_signature(self, **kwargs: Any) -> str:
17101726
documenter.object = func
17111727
documenter.objpath = [None]
17121728
sigs.append(documenter.format_signature())
1729+
if overloaded:
1730+
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
1731+
if not inspect.isstaticmethod(self.object, cls=self.parent,
1732+
name=self.object_name):
1733+
parameters = list(overload.parameters.values())
1734+
overload = overload.replace(parameters=parameters[1:])
1735+
sig = stringify_signature(overload, **kwargs)
1736+
sigs.append(sig)
17131737

17141738
return "\n".join(sigs)
17151739

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from typing import overload
2+
3+
4+
@overload
5+
def sum(x: int, y: int) -> int:
6+
...
7+
8+
9+
@overload
10+
def sum(x: float, y: float) -> float:
11+
...
12+
13+
14+
@overload
15+
def sum(x: str, y: str) -> str:
16+
...
17+
18+
19+
def sum(x, y):
20+
"""docstring"""
21+
return x + y
22+
23+
24+
class Math:
25+
"""docstring"""
26+
27+
@overload
28+
def sum(self, x: int, y: int) -> int:
29+
...
30+
31+
@overload
32+
def sum(self, x: float, y: float) -> float:
33+
...
34+
35+
@overload
36+
def sum(self, x: str, y: str) -> str:
37+
...
38+
39+
def sum(self, x, y):
40+
"""docstring"""
41+
return x + y

tests/test_ext_autodoc.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,39 @@ def test_final(app):
17871787
]
17881788

17891789

1790+
@pytest.mark.sphinx('html', testroot='ext-autodoc')
1791+
def test_overload(app):
1792+
options = {"members": None}
1793+
actual = do_autodoc(app, 'module', 'target.overload', options)
1794+
assert list(actual) == [
1795+
'',
1796+
'.. py:module:: target.overload',
1797+
'',
1798+
'',
1799+
'.. py:class:: Math()',
1800+
' :module: target.overload',
1801+
'',
1802+
' docstring',
1803+
'',
1804+
'',
1805+
' .. py:method:: Math.sum(x: int, y: int) -> int',
1806+
' Math.sum(x: float, y: float) -> float',
1807+
' Math.sum(x: str, y: str) -> str',
1808+
' :module: target.overload',
1809+
'',
1810+
' docstring',
1811+
'',
1812+
'',
1813+
'.. py:function:: sum(x: int, y: int) -> int',
1814+
' sum(x: float, y: float) -> float',
1815+
' sum(x: str, y: str) -> str',
1816+
' :module: target.overload',
1817+
'',
1818+
' docstring',
1819+
'',
1820+
]
1821+
1822+
17901823
@pytest.mark.sphinx('dummy', testroot='ext-autodoc')
17911824
def test_autodoc(app, status, warning):
17921825
app.builder.build_all()

0 commit comments

Comments
 (0)