Closes #10310: Sphinx automodule: class method not documented when decorated with mocked function.

This commit is contained in:
Christian Walch
2022-03-31 09:19:46 +02:00
parent 4221d1a516
commit d3949f8481

View File

@@ -5,7 +5,7 @@ import os
import sys
from importlib.abc import Loader, MetaPathFinder
from importlib.machinery import ModuleSpec
from types import ModuleType
from types import MethodType, ModuleType
from typing import Any, Generator, Iterator, List, Optional, Sequence, Tuple, Union
from sphinx.util import logging
@@ -129,6 +129,13 @@ class MockFinder(MetaPathFinder):
sys.modules.pop(modname, None)
def _method_is_bound(method):
try:
return method.__self__ is not None
except AttributeError:
return False
@contextlib.contextmanager
def mock(modnames: List[str]) -> Generator[None, None, None]:
"""Insert mock modules during context::
@@ -164,9 +171,15 @@ def ismock(subject: Any) -> bool:
if isinstance(subject, _MockModule):
return True
# check the object is bound method
if isinstance(subject, MethodType) and _method_is_bound(subject):
tmp_subject = subject.__func__
else:
tmp_subject = subject
try:
# check the object is mocked object
__mro__ = safe_getattr(type(subject), '__mro__', [])
__mro__ = safe_getattr(type(tmp_subject), '__mro__', [])
if len(__mro__) > 2 and __mro__[-2] is _MockObject:
# A mocked object has a MRO that ends with (..., _MockObject, object).
return True
@@ -175,7 +188,6 @@ def ismock(subject: Any) -> bool:
return False
def undecorate(subject: _MockObject) -> Any:
"""Unwrap mock if *subject* is decorated by mocked object.