summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-12-22 02:21:27 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-12-22 02:38:31 +0900
commit70bb2262d6677e5bcf2c85786b5f410a3a0f68aa (patch)
tree680fbc9d1f5653184d23ec129e945dce082a08d3
parent31cad2ebe7a205154e1374bfa52338111e515719 (diff)
downloadsphinx-git-70bb2262d6677e5bcf2c85786b5f410a3a0f68aa.tar.gz
Fix #8567: autodoc: Instance attributes are incorrectly added to Parent class
The instance attributes on subclasses are shown on the document of parent class unexpectedly because of autodoc modifies `__annotations__` in place. This fix creates a copy of `__annotations__` attribute and attach it to the subclass.
-rw-r--r--CHANGES1
-rw-r--r--sphinx/ext/autodoc/__init__.py13
-rw-r--r--tests/test_ext_autodoc.py1
3 files changed, 11 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index 6125b83a1..7241391ae 100644
--- a/CHANGES
+++ b/CHANGES
@@ -19,6 +19,7 @@ Bugs fixed
* #8559: autodoc: AttributeError is raised when using forward-reference type
annotations
* #8568: autodoc: TypeError is raised on checking slots attribute
+* #8567: autodoc: Instance attributes are incorrectly added to Parent class
Testing
--------
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 4bf97cc85..05696448d 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -1856,13 +1856,14 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin,
def update_annotations(self, parent: Any) -> None:
"""Update __annotations__ to support type_comment and so on."""
try:
- annotations = inspect.getannotations(parent)
+ annotations = dict(inspect.getannotations(parent))
+ parent.__annotations__ = annotations
analyzer = ModuleAnalyzer.for_module(self.modname)
analyzer.analyze()
for (classname, attrname), annotation in analyzer.annotations.items():
if classname == '' and attrname not in annotations:
- annotations[attrname] = annotation # type: ignore
+ annotations[attrname] = annotation
except AttributeError:
pass
@@ -2292,7 +2293,8 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type:
def update_annotations(self, parent: Any) -> None:
"""Update __annotations__ to support type_comment and so on."""
try:
- annotations = inspect.getannotations(parent)
+ annotations = dict(inspect.getannotations(parent))
+ parent.__annotations__ = annotations
for cls in inspect.getmro(parent):
try:
@@ -2303,11 +2305,14 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type:
analyzer.analyze()
for (classname, attrname), annotation in analyzer.annotations.items():
if classname == qualname and attrname not in annotations:
- annotations[attrname] = annotation # type: ignore
+ annotations[attrname] = annotation
except (AttributeError, PycodeError):
pass
except AttributeError:
pass
+ except TypeError:
+ # Failed to set __annotations__ (built-in, extensions, etc.)
+ pass
def import_object(self, raiseerror: bool = False) -> bool:
try:
diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py
index 392ad1a68..1fa0c1d7d 100644
--- a/tests/test_ext_autodoc.py
+++ b/tests/test_ext_autodoc.py
@@ -690,6 +690,7 @@ def test_autodoc_special_members(app):
actual = do_autodoc(app, 'class', 'target.Class', options)
assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Class(arg)',
+ ' .. py:attribute:: Class.__annotations__',
' .. py:attribute:: Class.__dict__',
' .. py:method:: Class.__init__(arg)',
' .. py:attribute:: Class.__module__',