Close #7165: autodoc: Support Annotated type (PEP-593)

This commit is contained in:
Takeshi KOMIYA 2020-03-03 00:07:19 +09:00
parent cdc7cc6fb3
commit 34057601f4
5 changed files with 37 additions and 1 deletions

View File

@ -52,6 +52,7 @@ Features added
not to document inherited members of the class and uppers not to document inherited members of the class and uppers
* #6830: autodoc: consider a member private if docstring contains * #6830: autodoc: consider a member private if docstring contains
``:meta private:`` in info-field-list ``:meta private:`` in info-field-list
* #7165: autodoc: Support Annotated type (PEP-593)
* #6558: glossary: emit a warning for duplicated glossary entry * #6558: glossary: emit a warning for duplicated glossary entry
* #3106: domain: Register hyperlink target for index page automatically * #3106: domain: Register hyperlink target for index page automatically
* #6558: std domain: emit a warning for duplicated generic objects * #6558: std domain: emit a warning for duplicated generic objects

View File

@ -49,7 +49,8 @@ def stringify(annotation: Any) -> str:
return repr(annotation) return repr(annotation)
elif annotation is NoneType: # type: ignore elif annotation is NoneType: # type: ignore
return 'None' return 'None'
elif getattr(annotation, '__module__', None) == 'builtins': elif (getattr(annotation, '__module__', None) == 'builtins' and
hasattr(annotation, '__qualname__')):
return annotation.__qualname__ return annotation.__qualname__
elif annotation is Ellipsis: elif annotation is Ellipsis:
return '...' return '...'
@ -88,6 +89,8 @@ def _stringify_py37(annotation: Any) -> str:
args = ', '.join(stringify(a) for a in annotation.__args__[:-1]) args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1]) returns = stringify(annotation.__args__[-1])
return '%s[[%s], %s]' % (qualname, args, returns) return '%s[[%s], %s]' % (qualname, args, returns)
elif str(annotation).startswith('typing.Annotated'): # for py39+
return stringify(annotation.__args__[0])
elif annotation._special: elif annotation._special:
return qualname return qualname
else: else:

View File

@ -0,0 +1,6 @@
from typing import Annotated
def hello(name: Annotated[str, "attribute"]) -> None:
"""docstring"""
pass

View File

@ -1524,6 +1524,24 @@ def test_autodoc_typed_instance_variables(app):
] ]
@pytest.mark.skipif(sys.version_info < (3, 9), reason='py39+ is required.')
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_Annotated(app):
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.annotated', options)
assert list(actual) == [
'',
'.. py:module:: target.annotated',
'',
'',
'.. py:function:: hello(name: str) -> None',
' :module: target.annotated',
'',
' docstring',
' '
]
@pytest.mark.sphinx('html', testroot='pycode-egg') @pytest.mark.sphinx('html', testroot='pycode-egg')
def test_autodoc_for_egged_code(app): def test_autodoc_for_egged_code(app):
options = {"members": None, options = {"members": None,

View File

@ -12,6 +12,8 @@ import sys
from numbers import Integral from numbers import Integral
from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional
import pytest
from sphinx.util.typing import stringify from sphinx.util.typing import stringify
@ -42,6 +44,12 @@ def test_stringify_type_hints_containers():
assert stringify(List[Dict[str, Tuple]]) == "List[Dict[str, Tuple]]" assert stringify(List[Dict[str, Tuple]]) == "List[Dict[str, Tuple]]"
@pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.')
def test_stringify_Annotated():
from typing import Annotated
assert stringify(Annotated[str, "foo", "bar"]) == "str"
def test_stringify_type_hints_string(): def test_stringify_type_hints_string():
assert stringify("int") == "int" assert stringify("int") == "int"
assert stringify("str") == "str" assert stringify("str") == "str"