Skip to content

Commit

Permalink
Closes #10310: Sphinx automodule: class method not documented when de…
Browse files Browse the repository at this point in the history
…corated with mocked function.
  • Loading branch information
Christian Walch committed Mar 31, 2022
1 parent 4221d1a commit d3949f8
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions sphinx/ext/autodoc/mock.py
Expand Up @@ -5,7 +5,7 @@
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
Expand Down Expand Up @@ -129,6 +129,13 @@ def invalidate_caches(self) -> None:
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::
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down

0 comments on commit d3949f8

Please sign in to comment.