Merge commit 'a82b06f2abb1226d82b18e3f85bdf19be7b9eb3f'

This commit is contained in:
Takeshi KOMIYA
2020-12-14 01:58:23 +09:00
7 changed files with 148 additions and 44 deletions

View File

@@ -70,7 +70,9 @@ Deprecated
----------
* The ``follow_wrapped`` argument of ``sphinx.util.inspect.signature()``
* ``sphinx.ext.autodoc.Documenter.get_object_members()``
* ``sphinx.ext.autodoc.DataDeclarationDocumenter``
* ``sphinx.ext.autodoc.TypeVarDocumenter``
* ``sphinx.ext.autodoc.importer._getannotations()``
* ``sphinx.pycode.ModuleAnalyzer.parse()``
* ``sphinx.util.requests.is_ssl_error()``
@@ -108,6 +110,8 @@ Bugs fixed
based uninitalized variables
* #8452: autodoc: autodoc_type_aliases doesn't work when autodoc_typehints is
set to "description"
* #8460: autodoc: autodata and autoattribute directives do not display type
information of TypeVars
* #8419: html search: Do not load ``language_data.js`` in non-search pages
* #8454: graphviz: The layout option for graph and digraph directives don't work
* #8437: Makefile: ``make clean`` with empty BUILDDIR is dangerous

View File

@@ -61,11 +61,21 @@ The following is a list of deprecated interfaces.
- 5.0
- N/A
* - ``sphinx.ext.autodoc.Documenter.get_object_members()``
- 3.4
- 6.0
- ``sphinx.ext.autodoc.ClassDocumenter.get_object_members()``
* - ``sphinx.ext.autodoc.DataDeclarationDocumenter``
- 3.4
- 5.0
- ``sphinx.ext.autodoc.DataDocumenter``
* - ``sphinx.ext.autodoc.TypeVarDocumenter``
- 3.4
- 5.0
- ``sphinx.ext.autodoc.DataDocumenter``
* - ``sphinx.ext.autodoc.importer._getannotations()``
- 3.4
- 4.0

View File

@@ -23,7 +23,7 @@ from docutils.statemachine import StringList
import sphinx
from sphinx.application import Sphinx
from sphinx.config import ENUM, Config
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.deprecation import RemovedInSphinx50Warning, RemovedInSphinx60Warning
from sphinx.environment import BuildEnvironment
from sphinx.ext.autodoc.importer import get_module_members, get_object_members, import_object
from sphinx.ext.autodoc.mock import mock
@@ -614,6 +614,8 @@ class Documenter:
If *want_all* is True, return all members. Else, only return those
members given by *self.options.members* (which may also be none).
"""
warnings.warn('The implementation of Documenter.get_object_members() will be '
'removed from Sphinx-6.0.', RemovedInSphinx60Warning)
members = get_object_members(self.object, self.objpath, self.get_attr, self.analyzer)
if not want_all:
if not self.options.members:
@@ -1564,6 +1566,26 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
bases = [restify(cls) for cls in self.object.__bases__]
self.add_line(' ' + _('Bases: %s') % ', '.join(bases), sourcename)
def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:
members = get_object_members(self.object, self.objpath, self.get_attr, self.analyzer)
if not want_all:
if not self.options.members:
return False, [] # type: ignore
# specific members given
selected = []
for name in self.options.members: # type: str
if name in members:
selected.append((name, members[name].value))
else:
logger.warning(__('missing attribute %s in object %s') %
(name, self.fullname), type='autodoc')
return False, selected
elif self.options.inherited_members:
return False, [(m.name, m.value) for m in members.values()]
else:
return False, [(m.name, m.value) for m in members.values()
if m.directly_defined]
def get_doc(self, ignore: int = None) -> List[List[str]]:
lines = getattr(self, '_new_docstrings', None)
if lines is not None:
@@ -1657,25 +1679,79 @@ class ExceptionDocumenter(ClassDocumenter):
return isinstance(member, type) and issubclass(member, BaseException)
class NewTypeMixin:
class DataDocumenterMixinBase:
# define types of instance variables
object = None # type: Any
def should_suppress_directive_header(self) -> bool:
"""Check directive header should be suppressed."""
return False
def update_content(self, more_content: StringList) -> None:
"""Update docstring for the NewType object."""
pass
class NewTypeMixin(DataDocumenterMixinBase):
"""
Mixin for DataDocumenter and AttributeDocumenter to provide the feature for
supporting NewTypes.
"""
def should_suppress_directive_header(self) -> bool:
"""Check directive header should be suppressed."""
return inspect.isNewType(self.object) # type: ignore
return (inspect.isNewType(self.object) or
super().should_suppress_directive_header())
def update_content(self, more_content: StringList) -> None:
"""Update docstring for the NewType object."""
if inspect.isNewType(self.object): # type: ignore
supertype = restify(self.object.__supertype__) # type: ignore
if inspect.isNewType(self.object):
supertype = restify(self.object.__supertype__)
more_content.append(_('alias of %s') % supertype, '')
more_content.append('', '')
super().update_content(more_content)
class DataDocumenter(ModuleLevelDocumenter, NewTypeMixin):
class TypeVarMixin(DataDocumenterMixinBase):
"""
Mixin for DataDocumenter and AttributeDocumenter to provide the feature for
supporting TypeVars.
"""
def should_suppress_directive_header(self) -> bool:
return (isinstance(self.object, TypeVar) or
super().should_suppress_directive_header())
def get_doc(self, ignore: int = None) -> List[List[str]]:
if ignore is not None:
warnings.warn("The 'ignore' argument to autodoc.%s.get_doc() is deprecated."
% self.__class__.__name__,
RemovedInSphinx50Warning, stacklevel=2)
if isinstance(self.object, TypeVar):
if self.object.__doc__ != TypeVar.__doc__:
return super().get_doc() # type: ignore
else:
return []
else:
return super().get_doc() # type: ignore
def update_content(self, more_content: StringList) -> None:
if isinstance(self.object, TypeVar):
attrs = [repr(self.object.__name__)]
for constraint in self.object.__constraints__:
attrs.append(stringify_typehint(constraint))
if self.object.__covariant__:
attrs.append("covariant=True")
if self.object.__contravariant__:
attrs.append("contravariant=True")
more_content.append(_('alias of TypeVar(%s)') % ", ".join(attrs), '')
more_content.append('', '')
super().update_content(more_content)
class DataDocumenter(NewTypeMixin, TypeVarMixin, ModuleLevelDocumenter):
"""
Specialized Documenter subclass for data items.
"""
@@ -1833,39 +1909,10 @@ class TypeVarDocumenter(DataDocumenter):
directivetype = 'data'
priority = DataDocumenter.priority + 1
@classmethod
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
) -> bool:
return isinstance(member, TypeVar) and isattr
def add_directive_header(self, sig: str) -> None:
self.options = Options(self.options)
self.options['annotation'] = SUPPRESS
super().add_directive_header(sig)
def get_doc(self, ignore: int = None) -> List[List[str]]:
if ignore is not None:
warnings.warn("The 'ignore' argument to autodoc.%s.get_doc() is deprecated."
% self.__class__.__name__,
RemovedInSphinx50Warning, stacklevel=2)
if self.object.__doc__ != TypeVar.__doc__:
return super().get_doc()
else:
return []
def add_content(self, more_content: Optional[StringList], no_docstring: bool = False
) -> None:
attrs = [repr(self.object.__name__)]
for constraint in self.object.__constraints__:
attrs.append(stringify_typehint(constraint))
if self.object.__covariant__:
attrs.append("covariant=True")
if self.object.__contravariant__:
attrs.append("contravariant=True")
content = StringList([_('alias of TypeVar(%s)') % ", ".join(attrs)], source='')
super().add_content(content)
def __init__(self, *args: Any, **kwargs: Any) -> None:
warnings.warn("%s is deprecated." % self.__class__.__name__,
RemovedInSphinx50Warning, stacklevel=2)
super().__init__(*args, **kwargs)
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
@@ -2029,7 +2076,8 @@ class SingledispatchMethodDocumenter(MethodDocumenter):
super().__init__(*args, **kwargs)
class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter, NewTypeMixin): # type: ignore # NOQA
class AttributeDocumenter(NewTypeMixin, TypeVarMixin, # type: ignore
DocstringStripSignatureMixin, ClassLevelDocumenter):
"""
Specialized Documenter subclass for attributes.
"""
@@ -2360,7 +2408,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_autodocumenter(DataDocumenter)
app.add_autodocumenter(GenericAliasDocumenter)
app.add_autodocumenter(NewTypeDataDocumenter)
app.add_autodocumenter(TypeVarDocumenter)
app.add_autodocumenter(FunctionDocumenter)
app.add_autodocumenter(DecoratorDocumenter)
app.add_autodocumenter(MethodDocumenter)

View File

@@ -19,7 +19,8 @@ T6 = NewType("T6", int)
class Class:
# TODO: TypeVar
#: T1
T1 = TypeVar("T1")
#: T6
T6 = NewType("T6", int)

View File

@@ -1732,6 +1732,14 @@ def test_autodoc_TypeVar(app):
' :module: target.typevar',
'',
'',
' .. py:attribute:: Class.T1',
' :module: target.typevar',
'',
' T1',
'',
" alias of TypeVar('T1')",
'',
'',
' .. py:attribute:: Class.T6',
' :module: target.typevar',
'',
@@ -1747,6 +1755,7 @@ def test_autodoc_TypeVar(app):
'',
" alias of TypeVar('T1')",
'',
'',
'.. py:data:: T3',
' :module: target.typevar',
'',
@@ -1754,6 +1763,7 @@ def test_autodoc_TypeVar(app):
'',
" alias of TypeVar('T3', int, str)",
'',
'',
'.. py:data:: T4',
' :module: target.typevar',
'',
@@ -1761,6 +1771,7 @@ def test_autodoc_TypeVar(app):
'',
" alias of TypeVar('T4', covariant=True)",
'',
'',
'.. py:data:: T5',
' :module: target.typevar',
'',
@@ -1768,6 +1779,7 @@ def test_autodoc_TypeVar(app):
'',
" alias of TypeVar('T5', contravariant=True)",
'',
'',
'.. py:data:: T6',
' :module: target.typevar',
'',

View File

@@ -85,3 +85,18 @@ def test_autoattribute_NewType(app):
' alias of :class:`int`',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_TypeVar(app):
actual = do_autodoc(app, 'attribute', 'target.typevar.Class.T1')
assert list(actual) == [
'',
'.. py:attribute:: Class.T1',
' :module: target.typevar',
'',
' T1',
'',
" alias of TypeVar('T1')",
'',
]

View File

@@ -88,3 +88,18 @@ def test_autodata_NewType(app):
' alias of :class:`int`',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodata_TypeVar(app):
actual = do_autodoc(app, 'data', 'target.typevar.T1')
assert list(actual) == [
'',
'.. py:data:: T1',
' :module: target.typevar',
'',
' T1',
'',
" alias of TypeVar('T1')",
'',
]