mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #7189: autodoc: classmethod coroutines are not detected
This commit is contained in:
parent
130a0a7f38
commit
2fec37219f
1
CHANGES
1
CHANGES
@ -18,6 +18,7 @@ Bugs fixed
|
||||
|
||||
* #7184: autodoc: ``*args`` and ``**kwarg`` in type comments are not handled
|
||||
properly
|
||||
* #7189: autodoc: classmethod coroutines are not detected
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
@ -111,6 +111,19 @@ def getargspec(func):
|
||||
kwonlyargs, kwdefaults, annotations)
|
||||
|
||||
|
||||
def unwrap(obj: Any) -> Any:
|
||||
"""Get an original object from wrapped object."""
|
||||
while True:
|
||||
if ispartial(obj):
|
||||
obj = unpartial(obj)
|
||||
elif isclassmethod(obj):
|
||||
obj = obj.__func__
|
||||
elif isstaticmethod(obj):
|
||||
obj = obj.__func__
|
||||
else:
|
||||
return obj
|
||||
|
||||
|
||||
def isenumclass(x: Any) -> bool:
|
||||
"""Check if the object is subclass of enum."""
|
||||
return inspect.isclass(x) and issubclass(x, enum.Enum)
|
||||
@ -141,7 +154,7 @@ def isclassmethod(obj: Any) -> bool:
|
||||
"""Check if the object is classmethod."""
|
||||
if isinstance(obj, classmethod):
|
||||
return True
|
||||
elif inspect.ismethod(obj) and obj.__self__ is not None:
|
||||
elif inspect.ismethod(obj) and obj.__self__ is not None and isclass(obj.__self__):
|
||||
return True
|
||||
|
||||
return False
|
||||
@ -208,17 +221,17 @@ def isattributedescriptor(obj: Any) -> bool:
|
||||
|
||||
def isfunction(obj: Any) -> bool:
|
||||
"""Check if the object is function."""
|
||||
return inspect.isfunction(unpartial(obj))
|
||||
return inspect.isfunction(unwrap(obj))
|
||||
|
||||
|
||||
def isbuiltin(obj: Any) -> bool:
|
||||
"""Check if the object is builtin."""
|
||||
return inspect.isbuiltin(unpartial(obj))
|
||||
return inspect.isbuiltin(unwrap(obj))
|
||||
|
||||
|
||||
def iscoroutinefunction(obj: Any) -> bool:
|
||||
"""Check if the object is coroutine-function."""
|
||||
obj = unpartial(obj)
|
||||
obj = unwrap(obj)
|
||||
if hasattr(obj, '__code__') and inspect.iscoroutinefunction(obj):
|
||||
# check obj.__code__ because iscoroutinefunction() crashes for custom method-like
|
||||
# objects (see https://github.com/sphinx-doc/sphinx/issues/6605)
|
||||
|
@ -3,6 +3,16 @@ class AsyncClass:
|
||||
"""A documented coroutine function"""
|
||||
attr_coro_result = await _other_coro_func() # NOQA
|
||||
|
||||
@classmethod
|
||||
async def do_coroutine2(cls):
|
||||
"""A documented coroutine classmethod"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
async def do_coroutine3():
|
||||
"""A documented coroutine staticmethod"""
|
||||
pass
|
||||
|
||||
|
||||
async def _other_coro_func():
|
||||
return "run"
|
||||
|
@ -1319,7 +1319,23 @@ def test_coroutine():
|
||||
' :async:',
|
||||
' ',
|
||||
' A documented coroutine function',
|
||||
' '
|
||||
' ',
|
||||
' ',
|
||||
' .. py:method:: AsyncClass.do_coroutine2()',
|
||||
' :module: target.coroutine',
|
||||
' :async:',
|
||||
' :classmethod:',
|
||||
' ',
|
||||
' A documented coroutine classmethod',
|
||||
' ',
|
||||
' ',
|
||||
' .. py:method:: AsyncClass.do_coroutine3()',
|
||||
' :module: target.coroutine',
|
||||
' :async:',
|
||||
' :staticmethod:',
|
||||
' ',
|
||||
' A documented coroutine staticmethod',
|
||||
' ',
|
||||
]
|
||||
|
||||
|
||||
|
@ -419,6 +419,16 @@ def test_dict_customtype():
|
||||
assert "<CustomType(2)>: 2" in description
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='ext-autodoc')
|
||||
def test_isclassmethod(app):
|
||||
from target.methods import Base, Inherited
|
||||
|
||||
assert inspect.isclassmethod(Base.classmeth) is True
|
||||
assert inspect.isclassmethod(Base.meth) is False
|
||||
assert inspect.isclassmethod(Inherited.classmeth) is True
|
||||
assert inspect.isclassmethod(Inherited.meth) is False
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='ext-autodoc')
|
||||
def test_isstaticmethod(app):
|
||||
from target.methods import Base, Inherited
|
||||
|
Loading…
Reference in New Issue
Block a user