diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 2e16c40d1..760c8feed 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -602,17 +602,8 @@ class GoogleDocstring: def _parse_attributes_section(self, section: str) -> List[str]: lines = [] for _name, _type, _desc in self._consume_fields(): - if not _type and self._what in ('class', 'exception') and self._obj: - if self._config.napoleon_attr_annotations: - # cache the class annotations - if not hasattr(self, "_annotations"): - localns = getattr(self._config, "autodoc_type_aliases", {}) or {} - localns.update(getattr( - self._config, "napoleon_type_aliases", {} - ) or {}) - self._annotations = get_type_hints(self._obj, None, localns) - if _name in self._annotations: - _type = stringify_annotation(self._annotations[_name]) + if not _type: + _type = self._lookup_annotation(_name) if self._config.napoleon_use_ivar: _name = self._qualify_name(_name, self._obj) field = ':ivar %s: ' % _name @@ -817,6 +808,21 @@ class GoogleDocstring: lines = lines[start:end + 1] return lines + def _lookup_annotation(self, _name: str) -> str: + if self._config.napoleon_attr_annotations: + if self._what in ("class", "exception") and self._obj: + # cache the class annotations + if not hasattr(self, "_annotations"): + localns = getattr(self._config, "autodoc_type_aliases", {}) or {} + localns.update(getattr( + self._config, "napoleon_type_aliases", {} + ) or {}) + self._annotations = get_type_hints(self._obj, None, localns) + if _name in self._annotations: + return stringify_annotation(self._annotations[_name]) + # No annotation found + return "" + def _recombine_set_tokens(tokens: List[str]) -> List[str]: token_queue = collections.deque(tokens) @@ -1121,6 +1127,9 @@ class NumpyDocstring(GoogleDocstring): _name, _type = _name.strip(), _type.strip() _name = self._escape_args_and_kwargs(_name) + if parse_type and not _type: + _type = self._lookup_annotation(_name) + if prefer_type and not _type: _type, _name = _name, _type diff --git a/tests/ext_napoleon_pep526_data_numpy.py b/tests/ext_napoleon_pep526_data_numpy.py index eaf81950e..d13ba31fb 100644 --- a/tests/ext_napoleon_pep526_data_numpy.py +++ b/tests/ext_napoleon_pep526_data_numpy.py @@ -12,10 +12,10 @@ class PEP526NumpyClass: Attributes ---------- - attr 1: + attr1: Attr1 description - attr 2: + attr2: Attr2 description """ attr1: int diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 19f0d3e5a..7c73f94d5 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -25,9 +25,6 @@ from sphinx.ext.napoleon.docstring import (GoogleDocstring, NumpyDocstring, _token_type, _tokenize_type_spec) if sys.version_info >= (3, 6): - # TODO: enable imports when used - # import ext_napoleon_pep526_data_google - # import ext_napoleon_pep526_data_numpy from ext_napoleon_pep526_data_google import PEP526GoogleClass from ext_napoleon_pep526_data_numpy import PEP526NumpyClass @@ -1100,7 +1097,7 @@ Do as you please """ self.assertEqual(expected, actual) - def test_pep_526_annotations(self): + def test_pep526_annotations(self): if sys.version_info >= (3, 6): # Test class attributes annotations config = Config( @@ -1125,9 +1122,6 @@ Sample class with PEP 526 annotations and google docstring """ self.assertEqual(expected, actual) - # test module-level variables documentation - # TODO: use the ext_napoleon_pep526_data_google.module_level_var for that - class NumpyDocstringTest(BaseDocstringTest): docstrings = [( @@ -2439,10 +2433,9 @@ class TestNumpyDocstring: assert actual == expected - def test_pep_526_annotations(self): + def test_pep526_annotations(self): if sys.version_info >= (3, 6): # test class attributes annotations - # TODO: change this test after implementation in Numpy doc style config = Config( napoleon_attr_annotations=True ) @@ -2451,16 +2444,17 @@ class TestNumpyDocstring: expected = """\ Sample class with PEP 526 annotations and numpy docstring -.. attribute:: attr 1 +.. attribute:: attr1 Attr1 description -.. attribute:: attr 2 + :type: int + +.. attribute:: attr2 Attr2 description + + :type: str """ print(actual) assert expected == actual - - # test module-level variables documentation - # TODO: use the ext_napoleon_pep526_data_google.module_level_var for that