Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ Bugs fixed
English stemmer) and Dutch (which uses the Dutch Porter stemmer).
Patch by Hugo van Kemenade

* #14576: autodoc: Fix ``IndexError`` when an ``autodoc-process-signature``
handler returns a signature for a data or type object, which are documented
without one. The object was then rendered without its docstring.
Patch by Jhon Alvarez


Release 9.1.0 (released Dec 31, 2025)
=====================================
Expand Down
5 changes: 4 additions & 1 deletion sphinx/ext/autodoc/_dynamic/_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ def _format_signatures(
):
if len(result) == 2 and isinstance(result[0], str):
args, retann = result
signatures[0] = (args, retann if isinstance(retann, str) else '')
# Data and type objects skip signature extraction, so *signatures*
# may still be empty here. A handler is free to return a signature
# for them anyway, and slice assignment stores it either way.
signatures[:1] = [(args, retann if isinstance(retann, str) else '')]

if props.obj_type in {'module', 'data', 'type'}:
signatures[1:] = () # discard all signatures save the first
Expand Down
18 changes: 18 additions & 0 deletions tests/test_ext_autodoc/test_ext_autodoc_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,24 @@ def foo1(self, b, *c): # type: ignore[no-untyped-def]
assert format_sig('method', 'bar', H.foo1, events=events) == ('42', '')


def test_format_signatures_event_handler_on_data() -> None:
# A data object skips signature extraction, so *signatures* is still empty
# when the event fires. A handler may return a signature for it anyway.
def process_signature(*args: Any) -> tuple[str, str | None]:
return '()', None

events = FakeEvents()
events.connect('autodoc-process-signature', process_signature)

class CallableData:
class_var: Any

def __call__(self) -> None:
pass

assert format_sig('data', 'sig_bug', CallableData(), events=events) == ('()', '')


def test_format_functools_partial_signatures() -> None:
# test functions created via functools.partial
from functools import partial
Expand Down
Loading