mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7749 from tk0miya/4422_support_GenericAlias
Close #4422: autodoc: Support GenericAlias
This commit is contained in:
commit
3c0e3d6705
1
CHANGES
1
CHANGES
@ -50,6 +50,7 @@ Features added
|
||||
* #7384: autodoc: Support signatures defined by ``__new__()``, metaclasses and
|
||||
builtin base classes
|
||||
* #2106: autodoc: Support multiple signatures on docstring
|
||||
* #4422: autodoc: Support GenericAlias in Python 3.7 or above
|
||||
* #7466: autosummary: headings in generated documents are not translated
|
||||
* #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a
|
||||
caption to the toctree
|
||||
|
@ -1580,6 +1580,30 @@ class DataDeclarationDocumenter(DataDocumenter):
|
||||
super().add_content(more_content, no_docstring=True)
|
||||
|
||||
|
||||
class GenericAliasDocumenter(DataDocumenter):
|
||||
"""
|
||||
Specialized Documenter subclass for GenericAliases.
|
||||
"""
|
||||
|
||||
objtype = 'genericalias'
|
||||
directivetype = 'data'
|
||||
priority = DataDocumenter.priority + 1
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return inspect.isgenericalias(member)
|
||||
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
self.options.annotation = SUPPRESS # type: ignore
|
||||
super().add_directive_header(sig)
|
||||
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
name = stringify_typehint(self.object)
|
||||
content = StringList([_('alias of %s') % name], source='')
|
||||
super().add_content(content)
|
||||
|
||||
|
||||
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
|
||||
"""
|
||||
Specialized Documenter subclass for methods (normal, static and class).
|
||||
@ -1938,6 +1962,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_autodocumenter(ExceptionDocumenter)
|
||||
app.add_autodocumenter(DataDocumenter)
|
||||
app.add_autodocumenter(DataDeclarationDocumenter)
|
||||
app.add_autodocumenter(GenericAliasDocumenter)
|
||||
app.add_autodocumenter(FunctionDocumenter)
|
||||
app.add_autodocumenter(DecoratorDocumenter)
|
||||
app.add_autodocumenter(MethodDocumenter)
|
||||
|
@ -91,14 +91,14 @@ def setup_documenters(app: Any) -> None:
|
||||
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
||||
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
|
||||
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
|
||||
SlotsAttributeDocumenter, DataDeclarationDocumenter,
|
||||
SlotsAttributeDocumenter, DataDeclarationDocumenter, GenericAliasDocumenter,
|
||||
SingledispatchFunctionDocumenter,
|
||||
)
|
||||
documenters = [
|
||||
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
||||
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
|
||||
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
|
||||
SlotsAttributeDocumenter, DataDeclarationDocumenter,
|
||||
SlotsAttributeDocumenter, DataDeclarationDocumenter, GenericAliasDocumenter,
|
||||
SingledispatchFunctionDocumenter,
|
||||
] # type: List[Type[Documenter]]
|
||||
for documenter in documenters:
|
||||
|
@ -13,6 +13,7 @@ import enum
|
||||
import inspect
|
||||
import re
|
||||
import sys
|
||||
import types
|
||||
import typing
|
||||
import warnings
|
||||
from functools import partial, partialmethod
|
||||
@ -304,6 +305,18 @@ def isproperty(obj: Any) -> bool:
|
||||
return isinstance(obj, property)
|
||||
|
||||
|
||||
def isgenericalias(obj: Any) -> bool:
|
||||
"""Check if the object is GenericAlias."""
|
||||
if (hasattr(typing, '_GenericAlias') and # only for py37+
|
||||
isinstance(obj, typing._GenericAlias)): # type: ignore
|
||||
return True
|
||||
elif (hasattr(types, 'GenericAlias') and # only for py39+
|
||||
isinstance(obj, types.GenericAlias)): # type: ignore
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def safe_getattr(obj: Any, name: str, *defargs: Any) -> Any:
|
||||
"""A getattr() that turns all exceptions into AttributeErrors."""
|
||||
try:
|
||||
|
6
tests/roots/test-ext-autodoc/target/genericalias.py
Normal file
6
tests/roots/test-ext-autodoc/target/genericalias.py
Normal file
@ -0,0 +1,6 @@
|
||||
from typing import List, Callable
|
||||
|
||||
#: A list of int
|
||||
T = List[int]
|
||||
|
||||
C = Callable[[int], None] # a generic alias not having a doccomment
|
@ -1587,6 +1587,37 @@ def test_autodoc_typed_instance_variables(app):
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_GenericAlias(app):
|
||||
options = {"members": None,
|
||||
"undoc-members": None}
|
||||
actual = do_autodoc(app, 'module', 'target.genericalias', options)
|
||||
if sys.version_info < (3, 7):
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:module:: target.genericalias',
|
||||
'',
|
||||
'',
|
||||
'.. py:attribute:: T',
|
||||
' :module: target.genericalias',
|
||||
'',
|
||||
' alias of :class:`typing.List`',
|
||||
]
|
||||
else:
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:module:: target.genericalias',
|
||||
'',
|
||||
'',
|
||||
'.. py:data:: T',
|
||||
' :module: target.genericalias',
|
||||
'',
|
||||
' A list of int',
|
||||
'',
|
||||
' alias of List[int]',
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 9), reason='py39+ is required.')
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_Annotated(app):
|
||||
|
@ -560,6 +560,18 @@ def test_isproperty(app):
|
||||
assert inspect.isproperty(func) is False # function
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason='python 3.7+ is required.')
|
||||
@pytest.mark.sphinx(testroot='ext-autodoc')
|
||||
def test_isgenericalias(app):
|
||||
from target.genericalias import C, T
|
||||
from target.methods import Base
|
||||
|
||||
assert inspect.isgenericalias(C) is True
|
||||
assert inspect.isgenericalias(T) is True
|
||||
assert inspect.isgenericalias(object()) is False
|
||||
assert inspect.isgenericalias(Base) is False
|
||||
|
||||
|
||||
def test_unpartial():
|
||||
def func1(a, b, c):
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user