Merge branch '3.x' into 8460_TypeVar

This commit is contained in:
Takeshi KOMIYA 2020-11-23 13:58:41 +09:00 committed by GitHub
commit 5ebacaec89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 14 deletions

View File

@ -14,8 +14,10 @@ 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.DataDeclarationDocumenter`` * ``sphinx.ext.autodoc.DataDeclarationDocumenter``
* ``sphinx.ext.autodoc.TypeVarDocumenter`` * ``sphinx.ext.autodoc.TypeVarDocumenter``
* ``sphinx.ext.autodoc.importer._getannotations()``
* ``sphinx.pycode.ModuleAnalyzer.parse()`` * ``sphinx.pycode.ModuleAnalyzer.parse()``
* ``sphinx.util.requests.is_ssl_error()`` * ``sphinx.util.requests.is_ssl_error()``

View File

@ -31,6 +31,11 @@ The following is a list of deprecated interfaces.
- 5.0 - 5.0
- N/A - N/A
* - ``sphinx.ext.autodoc.Documenter.get_object_members()``
- 3.4
- 6.0
- ``sphinx.ext.autodoc.ClassDocumenter.get_object_members()``
* - ``sphinx.ext.autodoc.DataDeclarationDocumenter`` * - ``sphinx.ext.autodoc.DataDeclarationDocumenter``
- 3.4 - 3.4
- 5.0 - 5.0
@ -41,6 +46,11 @@ The following is a list of deprecated interfaces.
- 5.0 - 5.0
- ``sphinx.ext.autodoc.DataDocumenter`` - ``sphinx.ext.autodoc.DataDocumenter``
* - ``sphinx.ext.autodoc.importer._getannotations()``
- 3.4
- 4.0
- ``sphinx.util.inspect.getannotations()``
* - ``sphinx.pycode.ModuleAnalyzer.parse()`` * - ``sphinx.pycode.ModuleAnalyzer.parse()``
- 3.4 - 3.4
- 5.0 - 5.0

View File

@ -26,6 +26,10 @@ class RemovedInSphinx50Warning(PendingDeprecationWarning):
pass pass
class RemovedInSphinx60Warning(PendingDeprecationWarning):
pass
RemovedInNextVersionWarning = RemovedInSphinx40Warning RemovedInNextVersionWarning = RemovedInSphinx40Warning

View File

@ -23,7 +23,8 @@ from docutils.statemachine import StringList
import sphinx import sphinx
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.config import ENUM, Config from sphinx.config import ENUM, Config
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.deprecation import (RemovedInSphinx40Warning, RemovedInSphinx50Warning,
RemovedInSphinx60Warning)
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.ext.autodoc.importer import get_module_members, get_object_members, import_object from sphinx.ext.autodoc.importer import get_module_members, get_object_members, import_object
from sphinx.ext.autodoc.mock import mock from sphinx.ext.autodoc.mock import mock
@ -621,6 +622,8 @@ class Documenter:
If *want_all* is True, return all members. Else, only return those If *want_all* is True, return all members. Else, only return those
members given by *self.options.members* (which may also be none). 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) members = get_object_members(self.object, self.objpath, self.get_attr, self.analyzer)
if not want_all: if not want_all:
if not self.options.members: if not self.options.members:
@ -1580,6 +1583,26 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
bases = [restify(cls) for cls in self.object.__bases__] bases = [restify(cls) for cls in self.object.__bases__]
self.add_line(' ' + _('Bases: %s') % ', '.join(bases), sourcename) 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, encoding: str = None, ignore: int = None) -> List[List[str]]: def get_doc(self, encoding: str = None, ignore: int = None) -> List[List[str]]:
if encoding is not None: if encoding is not None:
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated." warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."

View File

@ -16,7 +16,7 @@ from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Optional, Tup
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.pycode import ModuleAnalyzer from sphinx.pycode import ModuleAnalyzer
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.inspect import getslots, isclass, isenumclass, safe_getattr from sphinx.util.inspect import getannotations, getslots, isclass, isenumclass, safe_getattr
if False: if False:
# For type annotation # For type annotation
@ -149,10 +149,12 @@ def get_module_members(module: Any) -> List[Tuple[str, Any]]:
continue continue
# annotation only member (ex. attr: int) # annotation only member (ex. attr: int)
if hasattr(module, '__annotations__'): try:
for name in module.__annotations__: for name in getannotations(module):
if name not in members: if name not in members:
members[name] = (name, INSTANCEATTR) members[name] = (name, INSTANCEATTR)
except AttributeError:
pass
return sorted(list(members.values())) return sorted(list(members.values()))
@ -172,12 +174,9 @@ def _getmro(obj: Any) -> Tuple["Type", ...]:
def _getannotations(obj: Any) -> Mapping[str, Any]: def _getannotations(obj: Any) -> Mapping[str, Any]:
"""Get __annotations__ from given *obj* safely.""" warnings.warn('sphinx.ext.autodoc.importer._getannotations() is deprecated.',
__annotations__ = safe_getattr(obj, '__annotations__', None) RemovedInSphinx40Warning)
if isinstance(__annotations__, Mapping): return getannotations(obj)
return __annotations__
else:
return {}
def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable, def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
@ -226,10 +225,13 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
# annotation only member (ex. attr: int) # annotation only member (ex. attr: int)
for i, cls in enumerate(_getmro(subject)): for i, cls in enumerate(_getmro(subject)):
for name in _getannotations(cls): try:
name = unmangle(cls, name) for name in getannotations(cls):
if name and name not in members: name = unmangle(cls, name)
members[name] = Attribute(name, i == 0, INSTANCEATTR) if name and name not in members:
members[name] = Attribute(name, i == 0, INSTANCEATTR)
except AttributeError:
pass
if analyzer: if analyzer:
# append instance attributes (cf. self.attr1) if analyzer knows # append instance attributes (cf. self.attr1) if analyzer knows

View File

@ -154,6 +154,18 @@ def getall(obj: Any) -> Optional[Sequence[str]]:
raise ValueError(__all__) raise ValueError(__all__)
def getannotations(obj: Any) -> Mapping[str, Any]:
"""Get __annotations__ from given *obj* safely.
Raises AttributeError if given *obj* raises an error on accessing __attribute__.
"""
__annotations__ = safe_getattr(obj, '__annotations__', None)
if isinstance(__annotations__, Mapping):
return __annotations__
else:
return {}
def getslots(obj: Any) -> Optional[Dict]: def getslots(obj: Any) -> Optional[Dict]:
"""Get __slots__ attribute of the class as dict. """Get __slots__ attribute of the class as dict.