Skip to content

Commit

Permalink
Merge pull request #9518 from jbms/fix-autodoc-docstring-signature-fo…
Browse files Browse the repository at this point in the history
…r-init-and-new

Fix autodoc_docstring_signature support for __init__ and __new__
  • Loading branch information
tk0miya committed Aug 1, 2021
2 parents f31d72c + 6c969ac commit 1cdde3d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
22 changes: 13 additions & 9 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -2234,6 +2234,12 @@ def dummy():
return None

def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
if self._new_docstrings is not None:
# docstring already returned previously, then modified by
# `DocstringSignatureMixin`. Just return the previously-computed
# result, so that we don't lose the processing done by
# `DocstringSignatureMixin`.
return self._new_docstrings
if self.objpath[-1] == '__init__':
docstring = getdoc(self.object, self.get_attr,
self.config.autodoc_inherit_docstrings,
Expand All @@ -2248,15 +2254,13 @@ def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
else:
return []
elif self.objpath[-1] == '__new__':
__new__ = self.get_attr(self.object, '__new__', None)
if __new__:
docstring = getdoc(__new__, self.get_attr,
self.config.autodoc_inherit_docstrings,
self.parent, self.object_name)
if (docstring is not None and
(docstring == object.__new__.__doc__ or # for pypy
docstring.strip() == object.__new__.__doc__)): # for !pypy
docstring = None
docstring = getdoc(self.object, self.get_attr,
self.config.autodoc_inherit_docstrings,
self.parent, self.object_name)
if (docstring is not None and
(docstring == object.__new__.__doc__ or # for pypy
docstring.strip() == object.__new__.__doc__)): # for !pypy
docstring = None
if docstring:
tab_width = self.directive.state.document.settings.tab_width
return [prepare_docstring(docstring, tabsize=tab_width)]
Expand Down
14 changes: 14 additions & 0 deletions tests/roots/test-ext-autodoc/target/__init__.py
Expand Up @@ -114,6 +114,20 @@ class InnerChild(Outer.Inner):


class DocstringSig(object):
def __new__(cls, *new_args, **new_kwargs):
"""__new__(cls, d, e=1) -> DocstringSig
First line of docstring
rest of docstring
"""

def __init__(self, *init_args, **init_kwargs):
"""__init__(self, a, b=1) -> None
First line of docstring
rest of docstring
"""

def meth(self):
"""meth(FOO, BAR=1) -> BAZ
First line of docstring
Expand Down
47 changes: 44 additions & 3 deletions tests/test_ext_autodoc_configs.py
Expand Up @@ -287,14 +287,34 @@ def test_autodoc_inherit_docstrings(app):

@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_docstring_signature(app):
options = {"members": None}
options = {"members": None, "special-members": "__init__, __new__"}
actual = do_autodoc(app, 'class', 'target.DocstringSig', options)
assert list(actual) == [
'',
'.. py:class:: DocstringSig()',
# FIXME: Ideally this would instead be: `DocstringSig(d, e=1)` but
# currently `ClassDocumenter` does not apply the docstring signature
# logic when extracting a signature from a __new__ or __init__ method.
'.. py:class:: DocstringSig(*new_args, **new_kwargs)',
' :module: target',
'',
'',
' .. py:method:: DocstringSig.__init__(self, a, b=1) -> None',
' :module: target',
'',
' First line of docstring',
'',
' rest of docstring',
'',
'',
' .. py:method:: DocstringSig.__new__(cls, d, e=1) -> DocstringSig',
' :module: target',
' :staticmethod:',
'',
' First line of docstring',
'',
' rest of docstring',
'',
'',
' .. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ',
' :module: target',
'',
Expand Down Expand Up @@ -331,10 +351,31 @@ def test_autodoc_docstring_signature(app):
actual = do_autodoc(app, 'class', 'target.DocstringSig', options)
assert list(actual) == [
'',
'.. py:class:: DocstringSig()',
'.. py:class:: DocstringSig(*new_args, **new_kwargs)',
' :module: target',
'',
'',
' .. py:method:: DocstringSig.__init__(*init_args, **init_kwargs)',
' :module: target',
'',
' __init__(self, a, b=1) -> None',
' First line of docstring',
'',
' rest of docstring',
'',
'',
'',
' .. py:method:: DocstringSig.__new__(cls, *new_args, **new_kwargs)',
' :module: target',
' :staticmethod:',
'',
' __new__(cls, d, e=1) -> DocstringSig',
' First line of docstring',
'',
' rest of docstring',
'',
'',
'',
' .. py:method:: DocstringSig.meth()',
' :module: target',
'',
Expand Down

0 comments on commit 1cdde3d

Please sign in to comment.