From 85567748d968cbd95587997788ba46cb29245b36 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 28 Dec 2020 21:46:57 +0900 Subject: [PATCH] Fix #8164: autodoc: Classes that inherit mocked class are not documented Use ismock() to check a module member is a mocked or not. It allows not to skip subclasses of mocked class. --- CHANGES | 2 ++ sphinx/ext/autodoc/__init__.py | 4 +-- .../test-ext-autodoc/target/need_mocks.py | 5 +++ tests/test_ext_autodoc_automodule.py | 31 +++++++++++++++++++ tests/test_ext_autodoc_configs.py | 3 ++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/test_ext_autodoc_automodule.py diff --git a/CHANGES b/CHANGES index 895293b7fb3..b237781769a 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,8 @@ Features added Bugs fixed ---------- +* #8164: autodoc: Classes that inherit mocked class are not documented + Testing -------- diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 85f9f6de255..a1c642703db 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -28,7 +28,7 @@ from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc.importer import (get_class_members, get_module_members, get_object_members, import_object) -from sphinx.ext.autodoc.mock import mock +from sphinx.ext.autodoc.mock import ismock, mock from sphinx.locale import _, __ from sphinx.pycode import ModuleAnalyzer, PycodeError from sphinx.util import inspect, logging @@ -731,7 +731,7 @@ def is_filtered_inherited_member(name: str) -> bool: isprivate = membername.startswith('_') keep = False - if safe_getattr(member, '__sphinx_mock__', None) is not None: + if ismock(member): # mocked module or object pass elif self.options.exclude_members and membername in self.options.exclude_members: diff --git a/tests/roots/test-ext-autodoc/target/need_mocks.py b/tests/roots/test-ext-autodoc/target/need_mocks.py index 275ce8d5f2d..bc227f24682 100644 --- a/tests/roots/test-ext-autodoc/target/need_mocks.py +++ b/tests/roots/test-ext-autodoc/target/need_mocks.py @@ -28,4 +28,9 @@ def decoratedMethod(self): return None +class Inherited(missing_module.Class): + """docstring""" + pass + + sphinx.missing_module4.missing_function(len(missing_name2)) diff --git a/tests/test_ext_autodoc_automodule.py b/tests/test_ext_autodoc_automodule.py new file mode 100644 index 00000000000..2fd20a611ea --- /dev/null +++ b/tests/test_ext_autodoc_automodule.py @@ -0,0 +1,31 @@ +""" + test_ext_autodoc_autocmodule + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Test the autodoc extension. This tests mainly the Documenters; the auto + directives are tested in a test source file translated by test_build. + + :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import sys + +import pytest + +from .test_ext_autodoc import do_autodoc + + +@pytest.mark.sphinx('html', testroot='ext-autodoc', + confoverrides={'autodoc_mock_imports': ['missing_module', + 'missing_package1', + 'missing_package2', + 'missing_package3', + 'sphinx.missing_module4']}) +@pytest.mark.usefixtures("rollback_sysmodules") +def test_subclass_of_mocked_object(app): + sys.modules.pop('target', None) # unload target module to clear the module cache + + options = {'members': True} + actual = do_autodoc(app, 'module', 'target.need_mocks', options) + assert '.. py:class:: Inherited(*args: Any, **kwargs: Any)' in actual diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py index ac0a2c11c1b..979c66d4732 100644 --- a/tests/test_ext_autodoc_configs.py +++ b/tests/test_ext_autodoc_configs.py @@ -429,7 +429,10 @@ def test_autoclass_content_and_docstring_signature_both(app): @pytest.mark.sphinx('html', testroot='ext-autodoc') +@pytest.mark.usefixtures("rollback_sysmodules") def test_mocked_module_imports(app, warning): + sys.modules.pop('target', None) # unload target module to clear the module cache + # no autodoc_mock_imports options = {"members": 'TestAutodoc,decoratedFunction,func'} actual = do_autodoc(app, 'module', 'target.need_mocks', options)