Skip to content

Commit

Permalink
Merge pull request #9905 from tk0miya/9883_ismock
Browse files Browse the repository at this point in the history
Fix #9883: autodoc: doccomment for the alias to mocked object was ignored
  • Loading branch information
tk0miya committed Nov 29, 2021
2 parents a7462d5 + f88ac53 commit e8e45a3
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CHANGES
Expand Up @@ -25,7 +25,8 @@ Features added
Bugs fixed
----------

* #9866: autodoc: doccoment for the imported class was ignored
* #9866: autodoc: doccomment for the imported class was ignored
* #9883: autodoc: doccomment for the alias to mocked object was ignored
* #9878: mathjax: MathJax configuration is placed after loading MathJax itself
* #9857: Generated RFC links use outdated base url

Expand Down
16 changes: 9 additions & 7 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -751,7 +751,7 @@ def is_filtered_inherited_member(name: str, obj: Any) -> bool:
isprivate = membername.startswith('_')

keep = False
if ismock(member):
if ismock(member) and (namespace, membername) not in attr_docs:
# mocked module or object
pass
elif self.options.exclude_members and membername in self.options.exclude_members:
Expand Down Expand Up @@ -2009,7 +2009,8 @@ def add_directive_header(self, sig: str) -> None:
self.add_line(' :type: ' + objrepr, sourcename)

try:
if self.options.no_value or self.should_suppress_value_header():
if (self.options.no_value or self.should_suppress_value_header() or
ismock(self.object)):
pass
else:
objrepr = object_description(self.object)
Expand Down Expand Up @@ -2528,11 +2529,11 @@ def is_function_or_method(obj: Any) -> bool:
@classmethod
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
) -> bool:
if inspect.isattributedescriptor(member):
if isinstance(parent, ModuleDocumenter):
return False
elif inspect.isattributedescriptor(member):
return True
elif (not isinstance(parent, ModuleDocumenter) and
not inspect.isroutine(member) and
not isinstance(member, type)):
elif not inspect.isroutine(member) and not isinstance(member, type):
return True
else:
return False
Expand Down Expand Up @@ -2625,7 +2626,8 @@ def add_directive_header(self, sig: str) -> None:
self.add_line(' :type: ' + objrepr, sourcename)

try:
if self.options.no_value or self.should_suppress_value_header():
if (self.options.no_value or self.should_suppress_value_header() or
ismock(self.object)):
pass
else:
objrepr = object_description(self.object)
Expand Down
3 changes: 2 additions & 1 deletion sphinx/ext/autodoc/mock.py
Expand Up @@ -170,7 +170,8 @@ def ismock(subject: Any) -> bool:
try:
# check the object is mocked object
__mro__ = safe_getattr(type(subject), '__mro__', [])
if len(__mro__) > 2 and __mro__[1] is _MockObject:
if len(__mro__) > 2 and __mro__[-2] is _MockObject:
# A mocked object has a MRO that ends with (..., _MockObject, object).
return True
except AttributeError:
pass
Expand Down
7 changes: 7 additions & 0 deletions tests/roots/test-ext-autodoc/target/need_mocks.py
Expand Up @@ -22,6 +22,10 @@ def func(arg: missing_module.Class):

class TestAutodoc(object):
"""TestAutodoc docstring."""

#: docstring
Alias = missing_module2.Class

@missing_name
def decoratedMethod(self):
"""TestAutodoc::decoratedMethod docstring"""
Expand All @@ -34,3 +38,6 @@ class Inherited(missing_module.Class):


sphinx.missing_module4.missing_function(len(missing_name2))

#: docstring
Alias = missing_module2.Class
14 changes: 13 additions & 1 deletion tests/test_ext_autodoc_configs.py
Expand Up @@ -536,7 +536,7 @@ 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'}
options = {"members": 'TestAutodoc,decoratedFunction,func,Alias'}
actual = do_autodoc(app, 'module', 'target.need_mocks', options)
assert list(actual) == []
assert "autodoc: failed to import module 'need_mocks'" in warning.getvalue()
Expand All @@ -557,12 +557,24 @@ def test_mocked_module_imports(app, warning):
'.. py:module:: target.need_mocks',
'',
'',
'.. py:data:: Alias',
' :module: target.need_mocks',
'',
' docstring',
'',
'',
'.. py:class:: TestAutodoc()',
' :module: target.need_mocks',
'',
' TestAutodoc docstring.',
'',
'',
' .. py:attribute:: TestAutodoc.Alias',
' :module: target.need_mocks',
'',
' docstring',
'',
'',
' .. py:method:: TestAutodoc.decoratedMethod()',
' :module: target.need_mocks',
'',
Expand Down
1 change: 1 addition & 0 deletions tests/test_ext_autodoc_mock.py
Expand Up @@ -146,6 +146,7 @@ class Inherited(mod1.Class):

assert ismock(mod1) is True
assert ismock(mod1.Class) is True
assert ismock(mod1.submod.Class) is True
assert ismock(Inherited) is False

assert ismock(mod2) is False
Expand Down

0 comments on commit e8e45a3

Please sign in to comment.