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 a crash (``list assignment index out of range``)
when an ``autodoc-process-signature`` event handler returns a
replacement signature for an object without one (e.g. a callable
data object).


Release 9.1.0 (released Dec 31, 2025)
=====================================
Expand Down
9 changes: 8 additions & 1 deletion sphinx/ext/autodoc/_dynamic/_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,14 @@ def _format_signatures(
):
if len(result) == 2 and isinstance(result[0], str):
args, retann = result
signatures[0] = (args, retann if isinstance(retann, str) else '')
signature = (args, retann if isinstance(retann, str) else '')
if signatures:
signatures[0] = signature
else:
# Some objects (e.g. data objects) never have a signature, but
# an event listener may still provide a replacement one.
# (https://github.com/sphinx-doc/sphinx/issues/14576)
signatures.append(signature)

if props.obj_type in {'module', 'data', 'type'}:
signatures[1:] = () # discard all signatures save the first
Expand Down
20 changes: 19 additions & 1 deletion tests/test_ext_autodoc/test_ext_autodoc_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from sphinx.ext.autodoc._shared import _AutodocConfig
from sphinx.util.inspect import safe_getattr

from tests.test_ext_autodoc.autodoc_util import FakeEvents
from tests.test_ext_autodoc.autodoc_util import FakeEvents, do_autodoc

TYPE_CHECKING = False
if TYPE_CHECKING:
Expand Down 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', '')


@pytest.mark.usefixtures('inject_autodoc_root_into_sys_path')
def test_data_object_signature_from_event_handler() -> None:
# https://github.com/sphinx-doc/sphinx/issues/14576
# Data objects never get a signature, but an ``autodoc-process-signature``
# listener may still provide a replacement one. That replacement must be
# appended rather than crashing on ``signatures[0]`` assignment.
def process_signature(app, what, name, obj, options, args, retann):
if what == 'data':
return '()', None
return None

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

content = do_autodoc('data', 'target.callable.function', events=events)
assert '.. py:data:: function()' in content


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