mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
added napoleon_google_attr_annotations option to use PEP 526 on google style
This commit is contained in:
parent
c941b9cb14
commit
f268665292
@ -294,3 +294,21 @@ class ExampleClass:
|
||||
|
||||
def _private_without_docstring(self):
|
||||
pass
|
||||
|
||||
class ExamplePEP526Class:
|
||||
"""The summary line for a class docstring should fit on one line.
|
||||
|
||||
If the class has public attributes, they may be documented here
|
||||
in an ``Attributes`` section and follow the same formatting as a
|
||||
function's ``Args`` section. If ``napoleon_google_attr_annotations``
|
||||
is True, types can be specified in the class body using ``PEP 526``
|
||||
annotations.
|
||||
|
||||
Attributes:
|
||||
attr1: Description of `attr1`.
|
||||
attr2: Description of `attr2`.
|
||||
|
||||
"""
|
||||
|
||||
attr1: str
|
||||
attr2: int
|
@ -203,7 +203,8 @@ Type Annotations
|
||||
This is an alternative to expressing types directly in docstrings.
|
||||
One benefit of expressing types according to `PEP 484`_ is that
|
||||
type checkers and IDEs can take advantage of them for static code
|
||||
analysis.
|
||||
analysis. `PEP 484`_ was then extended by `PEP 526`_ which introduced
|
||||
a similar way to annotate variables (and attributes).
|
||||
|
||||
Google style with Python 3 type annotations::
|
||||
|
||||
@ -221,6 +222,19 @@ Google style with Python 3 type annotations::
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
class Class:
|
||||
"""Summary line.
|
||||
|
||||
Extended description of class
|
||||
|
||||
Attributes:
|
||||
attr1: Description of attr1
|
||||
attr2: Description of attr2
|
||||
"""
|
||||
|
||||
attr1: int
|
||||
attr2: str
|
||||
|
||||
Google style with types in docstrings::
|
||||
|
||||
@ -238,6 +252,16 @@ Google style with types in docstrings::
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
class Class:
|
||||
"""Summary line.
|
||||
|
||||
Extended description of class
|
||||
|
||||
Attributes:
|
||||
attr1 (int): Description of attr1
|
||||
attr2 (str): Description of attr2
|
||||
"""
|
||||
|
||||
.. Note::
|
||||
`Python 2/3 compatible annotations`_ aren't currently
|
||||
@ -246,6 +270,9 @@ Google style with types in docstrings::
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
.. _PEP 526:
|
||||
https://www.python.org/dev/peps/pep-0526/
|
||||
|
||||
.. _Python 2/3 compatible annotations:
|
||||
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
||||
|
||||
@ -275,6 +302,7 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
||||
napoleon_use_param = True
|
||||
napoleon_use_rtype = True
|
||||
napoleon_type_aliases = None
|
||||
napoleon_google_attr_annotations = False
|
||||
|
||||
.. _Google style:
|
||||
https://google.github.io/styleguide/pyguide.html
|
||||
@ -511,3 +539,9 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
|
||||
:type arg2: :term:`dict-like <mapping>`
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. confval:: napoleon_google_attr_annotations
|
||||
|
||||
True to allow using `PEP 526`_ attributes annotations in classes.
|
||||
If an attribute is documented in the docstring without a type and
|
||||
has an annotation in the class body, that type is used.
|
@ -44,6 +44,7 @@ class Config:
|
||||
napoleon_preprocess_types = False
|
||||
napoleon_type_aliases = None
|
||||
napoleon_custom_sections = None
|
||||
napoleon_google_attr_annotations = False
|
||||
|
||||
.. _Google style:
|
||||
https://google.github.io/styleguide/pyguide.html
|
||||
@ -257,6 +258,9 @@ class Config:
|
||||
section. If the entry is a tuple/list/indexed container, the first entry
|
||||
is the name of the section, the second is the section key to emulate.
|
||||
|
||||
napoleon_google_attr_annotations : :obj:`bool` (Defaults to False)
|
||||
Use the type annotations of class attributes that are documented in the docstring
|
||||
but do not have a type in the docstring.
|
||||
|
||||
"""
|
||||
_config_values = {
|
||||
@ -274,7 +278,8 @@ class Config:
|
||||
'napoleon_use_keyword': (True, 'env'),
|
||||
'napoleon_preprocess_types': (False, 'env'),
|
||||
'napoleon_type_aliases': (None, 'env'),
|
||||
'napoleon_custom_sections': (None, 'env')
|
||||
'napoleon_custom_sections': (None, 'env'),
|
||||
'napoleon_google_attr_annotations': (False, 'env'),
|
||||
}
|
||||
|
||||
def __init__(self, **settings: Any) -> None:
|
||||
|
@ -14,13 +14,14 @@ import collections
|
||||
import inspect
|
||||
import re
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, List, Tuple, Union
|
||||
from typing import Any, Callable, Dict, List, Tuple, Union, get_type_hints
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.config import Config as SphinxConfig
|
||||
from sphinx.ext.napoleon.iterators import modify_iter
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.inspect import safe_getattr, stringify_annotation
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -600,6 +601,26 @@ class GoogleDocstring:
|
||||
def _parse_attributes_section(self, section: str) -> List[str]:
|
||||
lines = []
|
||||
for _name, _type, _desc in self._consume_fields():
|
||||
# code adapted from autodoc.AttributeDocumenter:add_directive_header
|
||||
if not _type and self._what == 'class' and self._obj:
|
||||
if self._config.napoleon_google_attr_annotations:
|
||||
# cache the class annotations
|
||||
if not hasattr(self, "_annotations"):
|
||||
try:
|
||||
self._annotations = get_type_hints(self._obj)
|
||||
except NameError:
|
||||
# Failed to evaluate ForwardRef (maybe TYPE_CHECKING)
|
||||
self._annotations = safe_getattr(self._obj, '__annotations__', {})
|
||||
except TypeError:
|
||||
self._annotations = {}
|
||||
except KeyError:
|
||||
# a broken class found (refs: https://github.com/sphinx-doc/sphinx/issues/8084)
|
||||
self._annotations = {}
|
||||
except AttributeError:
|
||||
# AttributeError is raised on 3.5.2 (fixed by 3.5.3)
|
||||
self._annotations = {}
|
||||
if _name in self._annotations:
|
||||
_type = stringify_annotation(self._annotations[_name])
|
||||
if self._config.napoleon_use_ivar:
|
||||
_name = self._qualify_name(_name, self._obj)
|
||||
field = ':ivar %s: ' % _name
|
||||
|
@ -45,6 +45,18 @@ class NamedtupleSubclass(namedtuple('NamedtupleSubclass', ('attr1', 'attr2'))):
|
||||
return super().__new__(cls, attr1, attr2)
|
||||
|
||||
|
||||
class PEP526Class:
|
||||
"""Sample class with PEP 526 annotations
|
||||
|
||||
Attributes:
|
||||
attr1: Attr1 description.
|
||||
attr2: Attr2 description.
|
||||
"""
|
||||
|
||||
attr1: int
|
||||
attr2: str
|
||||
|
||||
|
||||
class BaseDocstringTest(TestCase):
|
||||
pass
|
||||
|
||||
@ -1091,6 +1103,30 @@ Do as you please
|
||||
:kwtype gotham_is_yours: None
|
||||
"""
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_pep_526_annotations(self):
|
||||
config = Config(
|
||||
napoleon_google_attr_annotations=True
|
||||
)
|
||||
actual = str(GoogleDocstring(cleandoc(PEP526Class.__doc__), config, app=None, what="class",
|
||||
obj=PEP526Class))
|
||||
print(actual)
|
||||
expected = """\
|
||||
Sample class with PEP 526 annotations
|
||||
|
||||
.. attribute:: attr1
|
||||
|
||||
Attr1 description.
|
||||
|
||||
:type: int
|
||||
|
||||
.. attribute:: attr2
|
||||
|
||||
Attr2 description.
|
||||
|
||||
:type: str
|
||||
"""
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class NumpyDocstringTest(BaseDocstringTest):
|
||||
|
Loading…
Reference in New Issue
Block a user