From 2e3e22ee03f7093f62c53cab8efe0d21e79d2c14 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:06:59 +0200 Subject: [PATCH 1/8] apply the type preprocessor only after the check for prefer_type --- sphinx/ext/napoleon/docstring.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 95fb1e538..a41e9fdd4 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -1067,6 +1067,10 @@ class NumpyDocstring(GoogleDocstring): _name, _type = line, '' _name, _type = _name.strip(), _type.strip() _name = self._escape_args_and_kwargs(_name) + + if prefer_type and not _type: + _type, _name = _name, _type + if self._config.napoleon_use_param: _type = _convert_numpy_type_spec( _type, @@ -1074,8 +1078,6 @@ class NumpyDocstring(GoogleDocstring): translations=self._config.napoleon_type_aliases or {}, ) - if prefer_type and not _type: - _type, _name = _name, _type indent = self._get_indent(line) + 1 _desc = self._dedent(self._consume_indented_block(indent)) _desc = self.__class__(_desc, self._config).lines() From 697fc8b16c211dc8515afd3f6df8d7c3baca469d Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:25:57 +0200 Subject: [PATCH 2/8] add test for the raises, yields and returns sections --- tests/test_ext_napoleon_docstring.py | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 56812d193..017737387 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1607,6 +1607,20 @@ Example Function (""" Example Function +Raises +------ +CustomError + If the dimensions couldn't be parsed. + +""", """ +Example Function + +:raises package.CustomError: If the dimensions couldn't be parsed. +"""), + ################################ + (""" +Example Function + Raises ------ :class:`exc.InvalidDimensionsError` @@ -1619,7 +1633,7 @@ Example Function :raises exc.InvalidArgumentsError: """)] for docstring, expected in docstrings: - config = Config() + config = Config(napoleon_type_aliases={"CustomError": "package.CustomError"}) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) @@ -1646,6 +1660,43 @@ Example Function actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) + docstring = """ +Example Function + +Returns +------- +ndarray + A :math:`n \\times 2` array containing + a bunch of math items +""" + config = Config(napoleon_type_aliases={"ndarray": ":class:`numpy.ndarray`"}) + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + + def test_yield_types(self): + docstring = dedent(""" + Example Function + + Yields + ------ + scalar or array-like + The result of the computation + """) + expected = dedent(""" + Example Function + + :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation + """) + config = Config( + napoleon_type_aliases={ + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + ) + app = mock.Mock() + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + def test_section_header_underline_length(self): docstrings = [(""" Summary line From fa760c326a1a96e9fe9f373b9b94757dd636e12f Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:30:14 +0200 Subject: [PATCH 3/8] move the translations to a named variable --- tests/test_ext_napoleon_docstring.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 017737387..991e5a232 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1687,12 +1687,11 @@ ndarray :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation """) - config = Config( - napoleon_type_aliases={ - "scalar": ":term:`scalar`", - "array-like": ":class:`array-like `", - } - ) + translations = { + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + config = Config(napoleon_type_aliases=translations) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) From 278a057104a26e33b6a986f3a1184482b90cdbbd Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:35:39 +0200 Subject: [PATCH 4/8] move the return types and yield types tests to above the raises test --- tests/test_ext_napoleon_docstring.py | 81 +++++++++++++++------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 991e5a232..35e2f36bd 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1443,6 +1443,51 @@ arg_ : type self.assertEqual(expected, actual) + def test_return_types(self): + docstring = dedent(""" + Returns + ------- + DataFrame + a dataframe + """) + expected = dedent(""" + :returns: a dataframe + :rtype: :class:`~pandas.DataFrame` + """) + translations = { + "DataFrame": "~pandas.DataFrame", + } + config = Config( + napoleon_use_param=True, + napoleon_use_rtype=True, + napoleon_type_aliases=translations, + ) + actual = str(NumpyDocstring(docstring, config)) + self.assertEqual(expected, actual) + + def test_yield_types(self): + docstring = dedent(""" + Example Function + + Yields + ------ + scalar or array-like + The result of the computation + """) + expected = dedent(""" + Example Function + + :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation + """) + translations = { + "scalar": ":term:`scalar`", + "array-like": ":class:`array-like `", + } + config = Config(napoleon_type_aliases=translations) + app = mock.Mock() + actual = str(NumpyDocstring(docstring, config, app, "method")) + self.assertEqual(expected, actual) + def test_raises_types(self): docstrings = [(""" Example Function @@ -1660,42 +1705,6 @@ Example Function actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) - docstring = """ -Example Function - -Returns -------- -ndarray - A :math:`n \\times 2` array containing - a bunch of math items -""" - config = Config(napoleon_type_aliases={"ndarray": ":class:`numpy.ndarray`"}) - actual = str(NumpyDocstring(docstring, config, app, "method")) - self.assertEqual(expected, actual) - - def test_yield_types(self): - docstring = dedent(""" - Example Function - - Yields - ------ - scalar or array-like - The result of the computation - """) - expected = dedent(""" - Example Function - - :Yields: :term:`scalar` or :class:`array-like ` -- The result of the computation - """) - translations = { - "scalar": ":term:`scalar`", - "array-like": ":class:`array-like `", - } - config = Config(napoleon_type_aliases=translations) - app = mock.Mock() - actual = str(NumpyDocstring(docstring, config, app, "method")) - self.assertEqual(expected, actual) - def test_section_header_underline_length(self): docstrings = [(""" Summary line From 2c75aaaa5452ab093e71138b6f864859cfb08554 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 11:36:15 +0200 Subject: [PATCH 5/8] move the GoogleDocstring test to the appropriate test class --- tests/test_ext_napoleon_docstring.py | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 35e2f36bd..14929bc0d 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1078,6 +1078,22 @@ Methods: options={'noindex': True})) self.assertEqual(expected, actual) + def test_keywords_with_types(self): + docstring = """\ +Do as you please + +Keyword Args: + gotham_is_yours (None): shall interfere. +""" + actual = str(GoogleDocstring(docstring)) + expected = """\ +Do as you please + +:keyword gotham_is_yours: shall interfere. +:kwtype gotham_is_yours: None +""" + self.assertEqual(expected, actual) + class NumpyDocstringTest(BaseDocstringTest): docstrings = [( @@ -2191,22 +2207,6 @@ definition_after_normal_text : int actual = str(NumpyDocstring(docstring, config)) self.assertEqual(expected, actual) - def test_keywords_with_types(self): - docstring = """\ -Do as you please - -Keyword Args: - gotham_is_yours (None): shall interfere. -""" - actual = str(GoogleDocstring(docstring)) - expected = """\ -Do as you please - -:keyword gotham_is_yours: shall interfere. -:kwtype gotham_is_yours: None -""" - self.assertEqual(expected, actual) - @contextmanager def warns(warning, match): match_re = re.compile(match) From c812370427f2e60174f74938e3ee26c1c0849a66 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 4 Aug 2020 14:59:54 +0200 Subject: [PATCH 6/8] expect the normal raises and yields to be preprocessed, too --- tests/test_ext_napoleon_docstring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 14929bc0d..5900f37d1 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1175,7 +1175,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :returns: *str* -- Extended + :returns: :class:`str` -- Extended description of return value """ ), ( @@ -1191,7 +1191,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :returns: *str* -- Extended + :returns: :class:`str` -- Extended description of return value """ ), ( @@ -1227,7 +1227,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :Yields: *str* -- Extended + :Yields: :class:`str` -- Extended description of yielded value """ ), ( @@ -1243,7 +1243,7 @@ class NumpyDocstringTest(BaseDocstringTest): """ Single line summary - :Yields: *str* -- Extended + :Yields: :class:`str` -- Extended description of yielded value """ )] From 75602f290ad14c263d4b8243ab5788a4c33e5d15 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 6 Aug 2020 16:38:49 +0200 Subject: [PATCH 7/8] make sure the roles are stripped from invalid names, too --- sphinx/ext/napoleon/docstring.py | 3 +++ tests/test_ext_napoleon_docstring.py | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 1612a2d90..8e9e4d3d6 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -693,6 +693,9 @@ class GoogleDocstring: m = self._name_rgx.match(_type) if m and m.group('name'): _type = m.group('name') + elif _xref_regex.match(_type): + pos = _type.find('`') + _type = _type[pos + 1:-1] _type = ' ' + _type if _type else '' _desc = self._strip_empty(_desc) _descs = ' ' + '\n '.join(_desc) if any(_desc) else '' diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 74e54eded..d8ad64b96 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1682,6 +1682,20 @@ Example Function (""" Example Function +Raises +------ +AnotherError + If the dimensions couldn't be parsed. + +""", """ +Example Function + +:raises ~package.AnotherError: If the dimensions couldn't be parsed. +"""), + ################################ + (""" +Example Function + Raises ------ :class:`exc.InvalidDimensionsError` @@ -1694,7 +1708,11 @@ Example Function :raises exc.InvalidArgumentsError: """)] for docstring, expected in docstrings: - config = Config(napoleon_type_aliases={"CustomError": "package.CustomError"}) + translations = { + "CustomError": "package.CustomError", + "AnotherError": ":py:exc:`~package.AnotherError`", + } + config = Config(napoleon_type_aliases=translations) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) From 439f75afd256ae259a72e39d1cf0e31711b94a85 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 18 Aug 2020 16:01:52 +0200 Subject: [PATCH 8/8] enable preprocessing in the tests --- tests/test_ext_napoleon_docstring.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 538227514..da456e4a2 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -1543,6 +1543,7 @@ arg_ : type config = Config( napoleon_use_param=True, napoleon_use_rtype=True, + napoleon_preprocess_types=True, napoleon_type_aliases=translations, ) actual = str(NumpyDocstring(docstring, config)) @@ -1566,7 +1567,7 @@ arg_ : type "scalar": ":term:`scalar`", "array-like": ":class:`array-like `", } - config = Config(napoleon_type_aliases=translations) + config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual) @@ -1779,7 +1780,7 @@ Example Function "CustomError": "package.CustomError", "AnotherError": ":py:exc:`~package.AnotherError`", } - config = Config(napoleon_type_aliases=translations) + config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True) app = mock.Mock() actual = str(NumpyDocstring(docstring, config, app, "method")) self.assertEqual(expected, actual)