Skip to content

Commit

Permalink
Merge pull request #9285 from tk0miya/9283_autodoc_attribute_not_havi…
Browse files Browse the repository at this point in the history
…ng_comment

Fix #9283: autodoc: failed to build doc for attribute not commented
  • Loading branch information
tk0miya committed Jun 3, 2021
2 parents 01918fc + 9a9433e commit 69cbf7a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -59,6 +59,8 @@ Bugs fixed
undocumented
* #9185: autodoc: typehints for overloaded functions and methods are inaccurate
* #9250: autodoc: The inherited method not having docstring is wrongly parsed
* #9283: autodoc: autoattribute directive failed to generate document for an
attribute not having any comment
* #9270: html theme : pyramid theme generates incorrect logo links
* #9217: manpage: The name of manpage directory that is generated by
:confval:`man_make_section_directory` is not correct
Expand Down
27 changes: 27 additions & 0 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -2356,9 +2356,29 @@ def is_runtime_instance_attribute(self, parent: Any) -> bool:
# An instance variable defined in __init__().
if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore
return True
elif self.is_runtime_instance_attribute_not_commented(parent):
return True
else:
return False

def is_runtime_instance_attribute_not_commented(self, parent: Any) -> bool:
"""Check the subject is an attribute defined in __init__() without comment."""
for cls in inspect.getmro(parent):
try:
module = safe_getattr(cls, '__module__')
qualname = safe_getattr(cls, '__qualname__')

analyzer = ModuleAnalyzer.for_module(module)
analyzer.analyze()
if qualname and self.objpath:
key = '.'.join([qualname, self.objpath[-1]])
if key in analyzer.tagorder:
return True
except (AttributeError, PycodeError):
pass

return None

def import_object(self, raiseerror: bool = False) -> bool:
"""Check the existence of runtime instance attribute when failed to import the
attribute."""
Expand Down Expand Up @@ -2389,6 +2409,13 @@ def should_suppress_value_header(self) -> bool:
return (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE or
super().should_suppress_value_header())

def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
if (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE and
self.is_runtime_instance_attribute_not_commented(self.parent)):
return None
else:
return super().get_doc(ignore) # type: ignore


class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
"""
Expand Down
1 change: 1 addition & 0 deletions tests/roots/test-ext-autodoc/target/instance_variable.py
Expand Up @@ -8,3 +8,4 @@ class Bar(Foo):
def __init__(self):
self.attr2 = None #: docstring bar
self.attr3 = None #: docstring bar
self.attr4 = None
11 changes: 11 additions & 0 deletions tests/test_ext_autodoc_autoattribute.py
Expand Up @@ -100,6 +100,17 @@ def test_autoattribute_instance_variable_in_alias(app):
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_instance_variable_without_comment(app):
actual = do_autodoc(app, 'attribute', 'target.instance_variable.Bar.attr4')
assert list(actual) == [
'',
'.. py:attribute:: Bar.attr4',
' :module: target.instance_variable',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_slots_variable_list(app):
actual = do_autodoc(app, 'attribute', 'target.slots.Foo.attr')
Expand Down

0 comments on commit 69cbf7a

Please sign in to comment.