mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
autodoc: Support type annotations for variables
This commit is contained in:
parent
66e4897a05
commit
5e4e44c195
1
CHANGES
1
CHANGES
@ -47,6 +47,7 @@ Features added
|
||||
images (imagesize-1.2.0 or above is required)
|
||||
* #6994: imgconverter: Support illustrator file (.ai) to .png conversion
|
||||
* autodoc: Support Positional-Only Argument separator (PEP-570 compliant)
|
||||
* autodoc: Support type annotations for variables
|
||||
* #2755: autodoc: Add new event: :event:`autodoc-before-process-signature`
|
||||
* #2755: autodoc: Support type_comment style (ex. ``# type: (str) -> str``)
|
||||
annotation (python3.8+ or `typed_ast <https://github.com/python/typed_ast>`_
|
||||
|
@ -10,6 +10,7 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import re
|
||||
import warnings
|
||||
from types import ModuleType
|
||||
@ -33,6 +34,7 @@ from sphinx.util import logging
|
||||
from sphinx.util import rpartition
|
||||
from sphinx.util.docstrings import prepare_docstring
|
||||
from sphinx.util.inspect import getdoc, object_description, safe_getattr, stringify_signature
|
||||
from sphinx.util.typing import stringify as stringify_typehint
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -1233,11 +1235,18 @@ class DataDocumenter(ModuleLevelDocumenter):
|
||||
sourcename = self.get_sourcename()
|
||||
if not self.options.annotation:
|
||||
try:
|
||||
objrepr = object_description(self.object)
|
||||
annotations = getattr(self.parent, '__annotations__', {})
|
||||
if self.objpath[-1] in annotations:
|
||||
objrepr = stringify_typehint(annotations.get(self.objpath[-1]))
|
||||
self.add_line(' :type: ' + objrepr, sourcename)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
objrepr = object_description(self.object)
|
||||
self.add_line(' :value: ' + objrepr, sourcename)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.add_line(' :annotation: = ' + objrepr, sourcename)
|
||||
elif self.options.annotation is SUPPRESS:
|
||||
pass
|
||||
else:
|
||||
@ -1276,6 +1285,12 @@ class DataDeclarationDocumenter(DataDocumenter):
|
||||
"""Never import anything."""
|
||||
# disguise as a data
|
||||
self.objtype = 'data'
|
||||
try:
|
||||
# import module to obtain type annotation
|
||||
self.parent = importlib.import_module(self.modname)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
@ -1405,11 +1420,18 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||
if not self.options.annotation:
|
||||
if not self._datadescriptor:
|
||||
try:
|
||||
objrepr = object_description(self.object)
|
||||
annotations = getattr(self.parent, '__annotations__', {})
|
||||
if self.objpath[-1] in annotations:
|
||||
objrepr = stringify_typehint(annotations.get(self.objpath[-1]))
|
||||
self.add_line(' :type: ' + objrepr, sourcename)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
objrepr = object_description(self.object)
|
||||
self.add_line(' :value: ' + objrepr, sourcename)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.add_line(' :annotation: = ' + objrepr, sourcename)
|
||||
elif self.options.annotation is SUPPRESS:
|
||||
pass
|
||||
else:
|
||||
|
@ -906,7 +906,7 @@ def test_autodoc_module_scope(app):
|
||||
'',
|
||||
'.. py:attribute:: Class.mdocattr',
|
||||
' :module: target',
|
||||
' :annotation: = <_io.StringIO object>',
|
||||
' :value: <_io.StringIO object>',
|
||||
'',
|
||||
' should be documented as well - süß',
|
||||
' '
|
||||
@ -922,7 +922,7 @@ def test_autodoc_class_scope(app):
|
||||
'',
|
||||
'.. py:attribute:: Class.mdocattr',
|
||||
' :module: target',
|
||||
' :annotation: = <_io.StringIO object>',
|
||||
' :value: <_io.StringIO object>',
|
||||
'',
|
||||
' should be documented as well - süß',
|
||||
' '
|
||||
@ -942,12 +942,12 @@ def test_class_attributes(app):
|
||||
' ',
|
||||
' .. py:attribute:: AttCls.a1',
|
||||
' :module: target',
|
||||
' :annotation: = hello world',
|
||||
' :value: hello world',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: AttCls.a2',
|
||||
' :module: target',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' '
|
||||
]
|
||||
|
||||
@ -966,7 +966,7 @@ def test_instance_attributes(app):
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ca1',
|
||||
' :module: target',
|
||||
" :annotation: = 'a'",
|
||||
" :value: 'a'",
|
||||
' ',
|
||||
' Doc comment for class attribute InstAttCls.ca1.',
|
||||
' It can have multiple lines.',
|
||||
@ -974,28 +974,28 @@ def test_instance_attributes(app):
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ca2',
|
||||
' :module: target',
|
||||
" :annotation: = 'b'",
|
||||
" :value: 'b'",
|
||||
' ',
|
||||
' Doc comment for InstAttCls.ca2. One line only.',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ca3',
|
||||
' :module: target',
|
||||
" :annotation: = 'c'",
|
||||
" :value: 'c'",
|
||||
' ',
|
||||
' Docstring for class attribute InstAttCls.ca3.',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ia1',
|
||||
' :module: target',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' Doc comment for instance attribute InstAttCls.ia1',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ia2',
|
||||
' :module: target',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' Docstring for instance attribute InstAttCls.ia2.',
|
||||
' '
|
||||
@ -1014,7 +1014,7 @@ def test_instance_attributes(app):
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ca1',
|
||||
' :module: target',
|
||||
" :annotation: = 'a'",
|
||||
" :value: 'a'",
|
||||
' ',
|
||||
' Doc comment for class attribute InstAttCls.ca1.',
|
||||
' It can have multiple lines.',
|
||||
@ -1022,7 +1022,7 @@ def test_instance_attributes(app):
|
||||
' ',
|
||||
' .. py:attribute:: InstAttCls.ia1',
|
||||
' :module: target',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' Doc comment for instance attribute InstAttCls.ia1',
|
||||
' '
|
||||
@ -1090,28 +1090,28 @@ def test_enum_class(app):
|
||||
' ',
|
||||
' .. py:attribute:: EnumCls.val1',
|
||||
' :module: target.enum',
|
||||
' :annotation: = 12',
|
||||
' :value: 12',
|
||||
' ',
|
||||
' doc for val1',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: EnumCls.val2',
|
||||
' :module: target.enum',
|
||||
' :annotation: = 23',
|
||||
' :value: 23',
|
||||
' ',
|
||||
' doc for val2',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: EnumCls.val3',
|
||||
' :module: target.enum',
|
||||
' :annotation: = 34',
|
||||
' :value: 34',
|
||||
' ',
|
||||
' doc for val3',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: EnumCls.val4',
|
||||
' :module: target.enum',
|
||||
' :annotation: = 34',
|
||||
' :value: 34',
|
||||
' '
|
||||
]
|
||||
|
||||
@ -1121,7 +1121,7 @@ def test_enum_class(app):
|
||||
'',
|
||||
'.. py:attribute:: EnumCls.val1',
|
||||
' :module: target.enum',
|
||||
' :annotation: = 12',
|
||||
' :value: 12',
|
||||
'',
|
||||
' doc for val1',
|
||||
' '
|
||||
@ -1405,38 +1405,40 @@ def test_autodoc_typed_instance_variables(app):
|
||||
' ',
|
||||
' .. py:attribute:: Class.attr1',
|
||||
' :module: target.typed_vars',
|
||||
' :annotation: = 0',
|
||||
' :type: int',
|
||||
' :value: 0',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: Class.attr2',
|
||||
' :module: target.typed_vars',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: Class.attr3',
|
||||
' :module: target.typed_vars',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' attr3',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:attribute:: Class.attr4',
|
||||
' :module: target.typed_vars',
|
||||
' :annotation: = None',
|
||||
' :value: None',
|
||||
' ',
|
||||
' attr4',
|
||||
' ',
|
||||
'',
|
||||
'.. py:data:: attr1',
|
||||
' :module: target.typed_vars',
|
||||
" :annotation: = ''",
|
||||
' :type: str',
|
||||
" :value: ''",
|
||||
'',
|
||||
' attr1',
|
||||
' ',
|
||||
'',
|
||||
'.. py:data:: attr2',
|
||||
' :module: target.typed_vars',
|
||||
" :annotation: = None",
|
||||
" :value: None",
|
||||
'',
|
||||
' attr2',
|
||||
' '
|
||||
@ -1455,7 +1457,7 @@ def test_autodoc_for_egged_code(app):
|
||||
'',
|
||||
'.. py:data:: CONSTANT',
|
||||
' :module: sample',
|
||||
' :annotation: = 1',
|
||||
' :value: 1',
|
||||
'',
|
||||
' constant on sample.py',
|
||||
' ',
|
||||
|
Loading…
Reference in New Issue
Block a user