mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #10313 from GutiCW/feature-support_mocked_decorator_for_class_methods
Support mocked decorator for class methods
This commit is contained in:
@@ -5,11 +5,11 @@ 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
|
||||
from sphinx.util.inspect import safe_getattr
|
||||
from sphinx.util.inspect import isboundmethod, safe_getattr
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -164,9 +164,15 @@ def ismock(subject: Any) -> bool:
|
||||
if isinstance(subject, _MockModule):
|
||||
return True
|
||||
|
||||
# check the object is bound method
|
||||
if isinstance(subject, MethodType) and isboundmethod(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
|
||||
|
||||
@@ -12,7 +12,7 @@ from functools import partial, partialmethod
|
||||
from importlib import import_module
|
||||
from inspect import Parameter, isclass, ismethod, ismethoddescriptor, ismodule # NOQA
|
||||
from io import StringIO
|
||||
from types import ModuleType
|
||||
from types import MethodType, ModuleType
|
||||
from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Type, cast
|
||||
|
||||
from sphinx.pycode.ast import ast # for py36-37
|
||||
@@ -238,6 +238,11 @@ def isabstractmethod(obj: Any) -> bool:
|
||||
return safe_getattr(obj, '__isabstractmethod__', False) is True
|
||||
|
||||
|
||||
def isboundmethod(method: MethodType) -> bool:
|
||||
"""Check if the method is a bound method."""
|
||||
return safe_getattr(method, '__self__', None) is not None
|
||||
|
||||
|
||||
def is_cython_function_or_method(obj: Any) -> bool:
|
||||
"""Check if the object is a function or method in cython."""
|
||||
try:
|
||||
|
||||
@@ -114,6 +114,11 @@ def test_mock_decorator():
|
||||
def meth(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@mock.method_deco
|
||||
def class_meth(cls):
|
||||
pass
|
||||
|
||||
@mock.class_deco
|
||||
class Bar:
|
||||
pass
|
||||
@@ -124,6 +129,7 @@ def test_mock_decorator():
|
||||
|
||||
assert undecorate(func).__name__ == "func"
|
||||
assert undecorate(Foo.meth).__name__ == "meth"
|
||||
assert undecorate(Foo.class_meth).__name__ == "class_meth"
|
||||
assert undecorate(Bar).__name__ == "Bar"
|
||||
assert undecorate(Baz).__name__ == "Baz"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user