mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #8504 from tk0miya/deprecate_GenericAliasDocumenter
Fix #8503: autoattribute could not create document for a GenericAlias
This commit is contained in:
commit
aa84eea08b
3
CHANGES
3
CHANGES
@ -16,6 +16,7 @@ Deprecated
|
|||||||
* The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
* The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
|
||||||
* ``sphinx.ext.autodoc.Documenter.get_object_members()``
|
* ``sphinx.ext.autodoc.Documenter.get_object_members()``
|
||||||
* ``sphinx.ext.autodoc.DataDeclarationDocumenter``
|
* ``sphinx.ext.autodoc.DataDeclarationDocumenter``
|
||||||
|
* ``sphinx.ext.autodoc.GenericAliasDocumenter``
|
||||||
* ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
* ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
||||||
* ``sphinx.ext.autodoc.SlotsAttributeDocumenter``
|
* ``sphinx.ext.autodoc.SlotsAttributeDocumenter``
|
||||||
* ``sphinx.ext.autodoc.TypeVarDocumenter``
|
* ``sphinx.ext.autodoc.TypeVarDocumenter``
|
||||||
@ -60,6 +61,8 @@ Bugs fixed
|
|||||||
based uninitalized variables
|
based uninitalized variables
|
||||||
* #8480: autodoc: autoattribute could not create document for __slots__
|
* #8480: autodoc: autoattribute could not create document for __slots__
|
||||||
attributes
|
attributes
|
||||||
|
* #8503: autodoc: autoattribute could not create document for a GenericAlias as
|
||||||
|
class attributes correctly
|
||||||
* #8452: autodoc: autodoc_type_aliases doesn't work when autodoc_typehints is
|
* #8452: autodoc: autodoc_type_aliases doesn't work when autodoc_typehints is
|
||||||
set to "description"
|
set to "description"
|
||||||
* #8460: autodoc: autodata and autoattribute directives do not display type
|
* #8460: autodoc: autodata and autoattribute directives do not display type
|
||||||
|
@ -41,6 +41,11 @@ The following is a list of deprecated interfaces.
|
|||||||
- 5.0
|
- 5.0
|
||||||
- ``sphinx.ext.autodoc.DataDocumenter``
|
- ``sphinx.ext.autodoc.DataDocumenter``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.autodoc.GenericAliasDocumenter``
|
||||||
|
- 3.4
|
||||||
|
- 5.0
|
||||||
|
- ``sphinx.ext.autodoc.DataDocumenter``
|
||||||
|
|
||||||
* - ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
* - ``sphinx.ext.autodoc.InstanceAttributeDocumenter``
|
||||||
- 3.4
|
- 3.4
|
||||||
- 5.0
|
- 5.0
|
||||||
|
@ -1701,6 +1701,25 @@ class DataDocumenterMixinBase:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GenericAliasMixin(DataDocumenterMixinBase):
|
||||||
|
"""
|
||||||
|
Mixin for DataDocumenter and AttributeDocumenter to provide the feature for
|
||||||
|
supporting GenericAliases.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def should_suppress_directive_header(self) -> bool:
|
||||||
|
return (inspect.isgenericalias(self.object) or
|
||||||
|
super().should_suppress_directive_header())
|
||||||
|
|
||||||
|
def update_content(self, more_content: StringList) -> None:
|
||||||
|
if inspect.isgenericalias(self.object):
|
||||||
|
alias = stringify_typehint(self.object)
|
||||||
|
more_content.append(_('alias of %s') % alias, '')
|
||||||
|
more_content.append('', '')
|
||||||
|
|
||||||
|
super().update_content(more_content)
|
||||||
|
|
||||||
|
|
||||||
class NewTypeMixin(DataDocumenterMixinBase):
|
class NewTypeMixin(DataDocumenterMixinBase):
|
||||||
"""
|
"""
|
||||||
Mixin for DataDocumenter and AttributeDocumenter to provide the feature for
|
Mixin for DataDocumenter and AttributeDocumenter to provide the feature for
|
||||||
@ -1801,8 +1820,8 @@ class UninitializedGlobalVariableMixin(DataDocumenterMixinBase):
|
|||||||
super().add_content(more_content, no_docstring=no_docstring) # type: ignore
|
super().add_content(more_content, no_docstring=no_docstring) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class DataDocumenter(NewTypeMixin, TypeVarMixin, UninitializedGlobalVariableMixin,
|
class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin,
|
||||||
ModuleLevelDocumenter):
|
UninitializedGlobalVariableMixin, ModuleLevelDocumenter):
|
||||||
"""
|
"""
|
||||||
Specialized Documenter subclass for data items.
|
Specialized Documenter subclass for data items.
|
||||||
"""
|
"""
|
||||||
@ -1863,32 +1882,6 @@ class DataDocumenter(NewTypeMixin, TypeVarMixin, UninitializedGlobalVariableMixi
|
|||||||
super().add_content(more_content, no_docstring=no_docstring)
|
super().add_content(more_content, no_docstring=no_docstring)
|
||||||
|
|
||||||
|
|
||||||
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 = Options(self.options)
|
|
||||||
self.options['annotation'] = SUPPRESS
|
|
||||||
super().add_directive_header(sig)
|
|
||||||
|
|
||||||
def add_content(self, more_content: Optional[StringList], no_docstring: bool = False
|
|
||||||
) -> None:
|
|
||||||
name = stringify_typehint(self.object)
|
|
||||||
content = StringList([_('alias of %s') % name], source='')
|
|
||||||
super().add_content(content)
|
|
||||||
|
|
||||||
|
|
||||||
class NewTypeDataDocumenter(DataDocumenter):
|
class NewTypeDataDocumenter(DataDocumenter):
|
||||||
"""
|
"""
|
||||||
Specialized Documenter subclass for NewTypes.
|
Specialized Documenter subclass for NewTypes.
|
||||||
@ -2102,8 +2095,8 @@ class SlotsMixin(DataDocumenterMixinBase):
|
|||||||
return super().get_doc(encoding, ignore) # type: ignore
|
return super().get_doc(encoding, ignore) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class AttributeDocumenter(NewTypeMixin, SlotsMixin, TypeVarMixin, # type: ignore
|
class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type: ignore
|
||||||
DocstringStripSignatureMixin, ClassLevelDocumenter):
|
TypeVarMixin, DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||||
"""
|
"""
|
||||||
Specialized Documenter subclass for attributes.
|
Specialized Documenter subclass for attributes.
|
||||||
"""
|
"""
|
||||||
@ -2324,6 +2317,7 @@ def migrate_autodoc_member_order(app: Sphinx, config: Config) -> None:
|
|||||||
|
|
||||||
# for compatibility
|
# for compatibility
|
||||||
from sphinx.ext.autodoc.deprecated import DataDeclarationDocumenter # NOQA
|
from sphinx.ext.autodoc.deprecated import DataDeclarationDocumenter # NOQA
|
||||||
|
from sphinx.ext.autodoc.deprecated import GenericAliasDocumenter # NOQA
|
||||||
from sphinx.ext.autodoc.deprecated import InstanceAttributeDocumenter # NOQA
|
from sphinx.ext.autodoc.deprecated import InstanceAttributeDocumenter # NOQA
|
||||||
from sphinx.ext.autodoc.deprecated import SingledispatchFunctionDocumenter # NOQA
|
from sphinx.ext.autodoc.deprecated import SingledispatchFunctionDocumenter # NOQA
|
||||||
from sphinx.ext.autodoc.deprecated import SingledispatchMethodDocumenter # NOQA
|
from sphinx.ext.autodoc.deprecated import SingledispatchMethodDocumenter # NOQA
|
||||||
@ -2336,7 +2330,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_autodocumenter(ClassDocumenter)
|
app.add_autodocumenter(ClassDocumenter)
|
||||||
app.add_autodocumenter(ExceptionDocumenter)
|
app.add_autodocumenter(ExceptionDocumenter)
|
||||||
app.add_autodocumenter(DataDocumenter)
|
app.add_autodocumenter(DataDocumenter)
|
||||||
app.add_autodocumenter(GenericAliasDocumenter)
|
|
||||||
app.add_autodocumenter(NewTypeDataDocumenter)
|
app.add_autodocumenter(NewTypeDataDocumenter)
|
||||||
app.add_autodocumenter(FunctionDocumenter)
|
app.add_autodocumenter(FunctionDocumenter)
|
||||||
app.add_autodocumenter(DecoratorDocumenter)
|
app.add_autodocumenter(DecoratorDocumenter)
|
||||||
|
@ -109,3 +109,18 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
|||||||
warnings.warn("%s is deprecated." % self.__class__.__name__,
|
warnings.warn("%s is deprecated." % self.__class__.__name__,
|
||||||
RemovedInSphinx50Warning, stacklevel=2)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class GenericAliasDocumenter(DataDocumenter):
|
||||||
|
"""
|
||||||
|
Specialized Documenter subclass for GenericAliases.
|
||||||
|
"""
|
||||||
|
|
||||||
|
objtype = 'genericalias'
|
||||||
|
directivetype = 'data'
|
||||||
|
priority = DataDocumenter.priority + 1 # type: ignore
|
||||||
|
|
||||||
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
warnings.warn("%s is deprecated." % self.__class__.__name__,
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -87,15 +87,14 @@ AutosummaryEntry = NamedTuple('AutosummaryEntry', [('name', str),
|
|||||||
def setup_documenters(app: Any) -> None:
|
def setup_documenters(app: Any) -> None:
|
||||||
from sphinx.ext.autodoc import (AttributeDocumenter, ClassDocumenter, DataDocumenter,
|
from sphinx.ext.autodoc import (AttributeDocumenter, ClassDocumenter, DataDocumenter,
|
||||||
DecoratorDocumenter, ExceptionDocumenter,
|
DecoratorDocumenter, ExceptionDocumenter,
|
||||||
FunctionDocumenter, GenericAliasDocumenter,
|
FunctionDocumenter, MethodDocumenter, ModuleDocumenter,
|
||||||
MethodDocumenter, ModuleDocumenter,
|
|
||||||
NewTypeAttributeDocumenter, NewTypeDataDocumenter,
|
NewTypeAttributeDocumenter, NewTypeDataDocumenter,
|
||||||
PropertyDocumenter, SingledispatchFunctionDocumenter)
|
PropertyDocumenter, SingledispatchFunctionDocumenter)
|
||||||
documenters = [
|
documenters = [
|
||||||
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
||||||
FunctionDocumenter, MethodDocumenter, NewTypeAttributeDocumenter,
|
FunctionDocumenter, MethodDocumenter, NewTypeAttributeDocumenter,
|
||||||
NewTypeDataDocumenter, AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
|
NewTypeDataDocumenter, AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
|
||||||
GenericAliasDocumenter, SingledispatchFunctionDocumenter,
|
SingledispatchFunctionDocumenter,
|
||||||
] # type: List[Type[Documenter]]
|
] # type: List[Type[Documenter]]
|
||||||
for documenter in documenters:
|
for documenter in documenters:
|
||||||
app.registry.add_documenter(documenter.objtype, documenter)
|
app.registry.add_documenter(documenter.objtype, documenter)
|
||||||
|
@ -4,3 +4,8 @@ from typing import Callable, List
|
|||||||
T = List[int]
|
T = List[int]
|
||||||
|
|
||||||
C = Callable[[int], None] # a generic alias not having a doccomment
|
C = Callable[[int], None] # a generic alias not having a doccomment
|
||||||
|
|
||||||
|
|
||||||
|
class Class:
|
||||||
|
#: A list of int
|
||||||
|
T = List[int]
|
||||||
|
@ -1701,6 +1701,15 @@ def test_autodoc_GenericAlias(app):
|
|||||||
'.. py:module:: target.genericalias',
|
'.. py:module:: target.genericalias',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
'.. py:class:: Class()',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
' .. py:attribute:: Class.T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' alias of :class:`List`\\ [:class:`int`]',
|
||||||
|
'',
|
||||||
'.. py:attribute:: T',
|
'.. py:attribute:: T',
|
||||||
' :module: target.genericalias',
|
' :module: target.genericalias',
|
||||||
'',
|
'',
|
||||||
@ -1712,12 +1721,25 @@ def test_autodoc_GenericAlias(app):
|
|||||||
'.. py:module:: target.genericalias',
|
'.. py:module:: target.genericalias',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
'.. py:class:: Class()',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
' .. py:attribute:: Class.T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of int',
|
||||||
|
'',
|
||||||
|
' alias of List[int]',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
'.. py:data:: T',
|
'.. py:data:: T',
|
||||||
' :module: target.genericalias',
|
' :module: target.genericalias',
|
||||||
'',
|
'',
|
||||||
' A list of int',
|
' A list of int',
|
||||||
'',
|
'',
|
||||||
' alias of List[int]',
|
' alias of List[int]',
|
||||||
|
'',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,6 +107,32 @@ def test_autoattribute_slots_variable_str(app):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autoattribute_GenericAlias(app):
|
||||||
|
actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T')
|
||||||
|
if sys.version_info < (3, 7):
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:attribute:: Class.T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
' :value: typing.List[int]',
|
||||||
|
'',
|
||||||
|
' A list of int',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:attribute:: Class.T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of int',
|
||||||
|
'',
|
||||||
|
' alias of List[int]',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autoattribute_NewType(app):
|
def test_autoattribute_NewType(app):
|
||||||
actual = do_autodoc(app, 'attribute', 'target.typevar.Class.T6')
|
actual = do_autodoc(app, 'attribute', 'target.typevar.Class.T6')
|
||||||
|
@ -75,6 +75,32 @@ def test_autodata_type_comment(app):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autodata_GenericAlias(app):
|
||||||
|
actual = do_autodoc(app, 'data', 'target.genericalias.T')
|
||||||
|
if sys.version_info < (3, 7):
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:data:: T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
' :value: typing.List[int]',
|
||||||
|
'',
|
||||||
|
' A list of int',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:data:: T',
|
||||||
|
' :module: target.genericalias',
|
||||||
|
'',
|
||||||
|
' A list of int',
|
||||||
|
'',
|
||||||
|
' alias of List[int]',
|
||||||
|
'',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodata_NewType(app):
|
def test_autodata_NewType(app):
|
||||||
actual = do_autodoc(app, 'data', 'target.typevar.T6')
|
actual = do_autodoc(app, 'data', 'target.typevar.T6')
|
||||||
|
Loading…
Reference in New Issue
Block a user