diff --git a/CHANGES b/CHANGES index b237781769a..a9abad0671e 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,8 @@ Bugs fixed ---------- * #8164: autodoc: Classes that inherit mocked class are not documented +* #8602: autodoc: The ``autodoc-process-docstring`` event is emitted to the + non-datadescriptors unexpectedly Testing -------- diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index a1c642703db..4429a2516b3 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -2092,18 +2092,36 @@ class NonDataDescriptorMixin(DataDocumenterMixinBase): and :value: header will be suppressed unexpectedly. """ + def import_object(self, raiseerror: bool = False) -> bool: + ret = super().import_object(raiseerror) # type: ignore + if ret and not inspect.isattributedescriptor(self.object): + self.non_data_descriptor = True + else: + self.non_data_descriptor = False + + return ret + def should_suppress_value_header(self) -> bool: - return (inspect.isattributedescriptor(self.object) or + return (not getattr(self, 'non_data_descriptor', False) or super().should_suppress_directive_header()) def get_doc(self, encoding: str = None, ignore: int = None) -> List[List[str]]: - if not inspect.isattributedescriptor(self.object): + if getattr(self, 'non_data_descriptor', False): # the docstring of non datadescriptor is very probably the wrong thing # to display return [] else: return super().get_doc(encoding, ignore) # type: ignore + def add_content(self, more_content: Optional[StringList], no_docstring: bool = False + ) -> None: + if getattr(self, 'non_data_descriptor', False): + # the docstring of non datadescriptor is very probably the wrong thing + # to display + no_docstring = True + + super().add_content(more_content, no_docstring=no_docstring) # type: ignore + class SlotsMixin(DataDocumenterMixinBase): """ diff --git a/tests/test_ext_autodoc_events.py b/tests/test_ext_autodoc_events.py index ad6a811298a..d00dea180db 100644 --- a/tests/test_ext_autodoc_events.py +++ b/tests/test_ext_autodoc_events.py @@ -34,6 +34,23 @@ def on_process_docstring(app, what, name, obj, options, lines): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_process_docstring_for_nondatadescriptor(app): + def on_process_docstring(app, what, name, obj, options, lines): + raise + + app.connect('autodoc-process-docstring', on_process_docstring) + + actual = do_autodoc(app, 'attribute', 'target.AttCls.a1') + assert list(actual) == [ + '', + '.. py:attribute:: AttCls.a1', + ' :module: target', + ' :value: hello world', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_cut_lines(app): app.connect('autodoc-process-docstring',