Skip to content

Commit 1cdde3d

Browse files
authored
Merge pull request #9518 from jbms/fix-autodoc-docstring-signature-for-init-and-new
Fix autodoc_docstring_signature support for __init__ and __new__
2 parents f31d72c + 6c969ac commit 1cdde3d

File tree

3 files changed

+71
-12
lines changed

3 files changed

+71
-12
lines changed

sphinx/ext/autodoc/__init__.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,6 +2234,12 @@ def dummy():
22342234
return None
22352235

22362236
def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
2237+
if self._new_docstrings is not None:
2238+
# docstring already returned previously, then modified by
2239+
# `DocstringSignatureMixin`. Just return the previously-computed
2240+
# result, so that we don't lose the processing done by
2241+
# `DocstringSignatureMixin`.
2242+
return self._new_docstrings
22372243
if self.objpath[-1] == '__init__':
22382244
docstring = getdoc(self.object, self.get_attr,
22392245
self.config.autodoc_inherit_docstrings,
@@ -2248,15 +2254,13 @@ def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
22482254
else:
22492255
return []
22502256
elif self.objpath[-1] == '__new__':
2251-
__new__ = self.get_attr(self.object, '__new__', None)
2252-
if __new__:
2253-
docstring = getdoc(__new__, self.get_attr,
2254-
self.config.autodoc_inherit_docstrings,
2255-
self.parent, self.object_name)
2256-
if (docstring is not None and
2257-
(docstring == object.__new__.__doc__ or # for pypy
2258-
docstring.strip() == object.__new__.__doc__)): # for !pypy
2259-
docstring = None
2257+
docstring = getdoc(self.object, self.get_attr,
2258+
self.config.autodoc_inherit_docstrings,
2259+
self.parent, self.object_name)
2260+
if (docstring is not None and
2261+
(docstring == object.__new__.__doc__ or # for pypy
2262+
docstring.strip() == object.__new__.__doc__)): # for !pypy
2263+
docstring = None
22602264
if docstring:
22612265
tab_width = self.directive.state.document.settings.tab_width
22622266
return [prepare_docstring(docstring, tabsize=tab_width)]

tests/roots/test-ext-autodoc/target/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,20 @@ class InnerChild(Outer.Inner):
114114

115115

116116
class DocstringSig(object):
117+
def __new__(cls, *new_args, **new_kwargs):
118+
"""__new__(cls, d, e=1) -> DocstringSig
119+
First line of docstring
120+
121+
rest of docstring
122+
"""
123+
124+
def __init__(self, *init_args, **init_kwargs):
125+
"""__init__(self, a, b=1) -> None
126+
First line of docstring
127+
128+
rest of docstring
129+
"""
130+
117131
def meth(self):
118132
"""meth(FOO, BAR=1) -> BAZ
119133
First line of docstring

tests/test_ext_autodoc_configs.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,14 +287,34 @@ def test_autodoc_inherit_docstrings(app):
287287

288288
@pytest.mark.sphinx('html', testroot='ext-autodoc')
289289
def test_autodoc_docstring_signature(app):
290-
options = {"members": None}
290+
options = {"members": None, "special-members": "__init__, __new__"}
291291
actual = do_autodoc(app, 'class', 'target.DocstringSig', options)
292292
assert list(actual) == [
293293
'',
294-
'.. py:class:: DocstringSig()',
294+
# FIXME: Ideally this would instead be: `DocstringSig(d, e=1)` but
295+
# currently `ClassDocumenter` does not apply the docstring signature
296+
# logic when extracting a signature from a __new__ or __init__ method.
297+
'.. py:class:: DocstringSig(*new_args, **new_kwargs)',
295298
' :module: target',
296299
'',
297300
'',
301+
' .. py:method:: DocstringSig.__init__(self, a, b=1) -> None',
302+
' :module: target',
303+
'',
304+
' First line of docstring',
305+
'',
306+
' rest of docstring',
307+
'',
308+
'',
309+
' .. py:method:: DocstringSig.__new__(cls, d, e=1) -> DocstringSig',
310+
' :module: target',
311+
' :staticmethod:',
312+
'',
313+
' First line of docstring',
314+
'',
315+
' rest of docstring',
316+
'',
317+
'',
298318
' .. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ',
299319
' :module: target',
300320
'',
@@ -331,10 +351,31 @@ def test_autodoc_docstring_signature(app):
331351
actual = do_autodoc(app, 'class', 'target.DocstringSig', options)
332352
assert list(actual) == [
333353
'',
334-
'.. py:class:: DocstringSig()',
354+
'.. py:class:: DocstringSig(*new_args, **new_kwargs)',
335355
' :module: target',
336356
'',
337357
'',
358+
' .. py:method:: DocstringSig.__init__(*init_args, **init_kwargs)',
359+
' :module: target',
360+
'',
361+
' __init__(self, a, b=1) -> None',
362+
' First line of docstring',
363+
'',
364+
' rest of docstring',
365+
'',
366+
'',
367+
'',
368+
' .. py:method:: DocstringSig.__new__(cls, *new_args, **new_kwargs)',
369+
' :module: target',
370+
' :staticmethod:',
371+
'',
372+
' __new__(cls, d, e=1) -> DocstringSig',
373+
' First line of docstring',
374+
'',
375+
' rest of docstring',
376+
'',
377+
'',
378+
'',
338379
' .. py:method:: DocstringSig.meth()',
339380
' :module: target',
340381
'',

0 commit comments

Comments
 (0)