diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 47f6bcb2506..8c840488e3e 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1378,7 +1378,7 @@ def get_user_defined_function_or_method(obj: Any, attr: str) -> Any: if call is not None: self.env.app.emit('autodoc-before-process-signature', call, True) try: - sig = inspect.signature(call, bound_method=True) + sig = inspect.signature(call, bound_method=True, follow_wrapped=True) return type(self.object), '__call__', sig except ValueError: pass @@ -1388,7 +1388,7 @@ def get_user_defined_function_or_method(obj: Any, attr: str) -> Any: if new is not None: self.env.app.emit('autodoc-before-process-signature', new, True) try: - sig = inspect.signature(new, bound_method=True) + sig = inspect.signature(new, bound_method=True, follow_wrapped=True) return self.object, '__new__', sig except ValueError: pass @@ -1398,7 +1398,7 @@ def get_user_defined_function_or_method(obj: Any, attr: str) -> Any: if init is not None: self.env.app.emit('autodoc-before-process-signature', init, True) try: - sig = inspect.signature(init, bound_method=True) + sig = inspect.signature(init, bound_method=True, follow_wrapped=True) return self.object, '__init__', sig except ValueError: pass diff --git a/sphinx/ext/autodoc/type_comment.py b/sphinx/ext/autodoc/type_comment.py index 7f11e3d120d..dc57742a02f 100644 --- a/sphinx/ext/autodoc/type_comment.py +++ b/sphinx/ext/autodoc/type_comment.py @@ -119,7 +119,7 @@ def update_annotations_using_type_comments(app: Sphinx, obj: Any, bound_method: try: type_sig = get_type_comment(obj, bound_method) if type_sig: - sig = inspect.signature(obj, bound_method) + sig = inspect.signature(obj, bound_method, follow_wrapped=True) for param in sig.parameters.values(): if param.name not in obj.__annotations__: annotation = type_sig.parameters[param.name].annotation diff --git a/tests/roots/test-ext-autodoc/target/decorator.py b/tests/roots/test-ext-autodoc/target/decorator.py index 61398b324e3..c51b71965f5 100644 --- a/tests/roots/test-ext-autodoc/target/decorator.py +++ b/tests/roots/test-ext-autodoc/target/decorator.py @@ -29,3 +29,21 @@ class Bar: @deco1 def meth(self, name=None, age=None): pass + + +class BarCall: + @deco1 + def __call__(self, name=None, age=None): + pass + + +class BarNew: + @deco1 + def __new__(cls, name=None, age=None): + pass + + +class BarInit: + @deco1 + def __init__(self, name=None, age=None): + pass diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 15e1f35395e..b86da3f3605 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -1286,6 +1286,39 @@ def test_automethod_for_decorated(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autoclass_for_decorated_call(app): + actual = do_autodoc(app, 'class', 'target.decorator.BarCall') + assert list(actual) == [ + '', + '.. py:class:: BarCall(name=None, age=None)', + ' :module: target.decorator', + '', + ] + + +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autoclass_for_decorated_new(app): + actual = do_autodoc(app, 'class', 'target.decorator.BarNew') + assert list(actual) == [ + '', + '.. py:class:: BarNew(name=None, age=None)', + ' :module: target.decorator', + '', + ] + + +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autoclass_for_decorated_init(app): + actual = do_autodoc(app, 'class', 'target.decorator.BarInit') + assert list(actual) == [ + '', + '.. py:class:: BarInit(name=None, age=None)', + ' :module: target.decorator', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_abstractmethods(app): options = {"members": None,