Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #7780: napoleon: multiple params declaration was wrongly recognized #8056

Merged
merged 2 commits into from Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -80,6 +80,8 @@ Bugs fixed
module has submodules
* #4258: napoleon: decorated special methods are not shown
* #7799: napoleon: parameters are not escaped for combined params in numpydoc
* #7780: napoleon: multiple paramaters declaration in numpydoc was wrongly
recognized when napoleon_use_params=True
* #7715: LaTeX: ``numfig_secnum_depth > 1`` leads to wrong figure links
* #7846: html theme: XML-invalid files were generated
* #7894: gettext: Wrong source info is shown when using rst_epilog
Expand Down
13 changes: 9 additions & 4 deletions sphinx/ext/napoleon/docstring.py
Expand Up @@ -266,13 +266,16 @@ def _consume_field(self, parse_type: bool = True, prefer_type: bool = False
_descs = self.__class__(_descs, self._config).lines()
return _name, _type, _descs

def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False
) -> List[Tuple[str, str, List[str]]]:
def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False,
multiple: bool = False) -> List[Tuple[str, str, List[str]]]:
self._consume_empty()
fields = []
while not self._is_section_break():
_name, _type, _desc = self._consume_field(parse_type, prefer_type)
if _name or _type or _desc:
if multiple and _name:
for name in _name.split(","):
fields.append((name.strip(), _type, _desc))
elif _name or _type or _desc:
fields.append((_name, _type, _desc,))
return fields

Expand Down Expand Up @@ -681,10 +684,12 @@ def _parse_other_parameters_section(self, section: str) -> List[str]:
return self._format_fields(_('Other Parameters'), self._consume_fields())

def _parse_parameters_section(self, section: str) -> List[str]:
fields = self._consume_fields()
if self._config.napoleon_use_param:
# Allow to declare multiple parameters at once (ex: x, y: int)
fields = self._consume_fields(multiple=True)
return self._format_docutils_params(fields)
else:
fields = self._consume_fields()
return self._format_fields(_('Parameters'), fields)

def _parse_raises_section(self, section: str) -> List[str]:
Expand Down
28 changes: 27 additions & 1 deletion tests/test_ext_napoleon_docstring.py
Expand Up @@ -1230,7 +1230,7 @@ class NumpyDocstringTest(BaseDocstringTest):
"""
Single line summary

:Parameters: * **arg1** (*str*) -- Extended description of arg1
:Parameters: * **arg1** (:class:`str`) -- Extended description of arg1
* **\\*args, \\*\\*kwargs** -- Variable length argument list and arbitrary keyword arguments.
"""
), (
Expand Down Expand Up @@ -1337,6 +1337,32 @@ def test_parameters_with_class_reference(self):
expected = """\
:param param1:
:type param1: :class:`MyClass <name.space.MyClass>` instance
"""
self.assertEqual(expected, actual)

def test_multiple_parameters(self):
docstring = """\
Parameters
----------
x1, x2 : array_like
Input arrays, description of ``x1``, ``x2``.

"""

config = Config(napoleon_use_param=False)
actual = str(NumpyDocstring(docstring, config))
expected = """\
:Parameters: **x1, x2** (:class:`array_like`) -- Input arrays, description of ``x1``, ``x2``.
"""
self.assertEqual(expected, actual)

config = Config(napoleon_use_param=True)
actual = str(NumpyDocstring(dedent(docstring), config))
expected = """\
:param x1: Input arrays, description of ``x1``, ``x2``.
:type x1: :class:`array_like`
:param x2: Input arrays, description of ``x1``, ``x2``.
:type x2: :class:`array_like`
"""
self.assertEqual(expected, actual)

Expand Down