Skip to content

Store a handler-supplied signature for objects that have none - #14627

Closed
SirHegel wants to merge 1 commit into
sphinx-doc:masterfrom
SirHegel:append-signature-when-none-extracted
Closed

Store a handler-supplied signature for objects that have none#14627
SirHegel wants to merge 1 commit into
sphinx-doc:masterfrom
SirHegel:append-signature-when-none-extracted

Conversation

@SirHegel

Copy link
Copy Markdown

Closes #14576.

The problem

_format_signatures reads signatures[0] defensively when emitting autodoc-process-signature:

        signatures[0][0] if signatures else None,  # args
        signatures[0][1] if signatures else '',  # retann
    ):
        if len(result) == 2 and isinstance(result[0], str):
            args, retann = result
            signatures[0] = (args, retann if isinstance(retann, str) else '')

and then writes signatures[0] unconditionally. Data and type objects skip signature extraction, so for them that list is empty and the write raises IndexError. It is caught and logged, and the object loses its docstring:

WARNING: error while formatting signature for mod.sig_bug:
list assignment index out of range [autodoc]

The reporter diagnosed this precisely in the issue; I reproduced it with their module and a conf.py handler, which is the documented way to use the event:

def process_signature(app, objtype, name, obj, options, args, retann):
    if objtype != "data":
        return None
    return ("()", None)

def setup(app):
    app.connect("autodoc-process-signature", process_signature)

Before: the warning above, and trigger (the #: docstring) appears 0 times in the built HTML.
After: build succeeded., and trigger appears 1 time.

The change

signatures[:1] = [...] instead of signatures[0] = .... Slice assignment stores the signature whether or not one was already extracted, and is identical to the old behaviour when the list is non-empty.

The if props.obj_type in {'module', 'data', 'type'}: signatures[1:] = () a few lines below already uses the same idiom for the same reason.

Tests

test_format_signatures_event_handler_on_data in tests/test_ext_autodoc/test_ext_autodoc_signatures.py. On master it fails with the exact error from the issue:

E               IndexError: list assignment index out of range
sphinx/ext/autodoc/_dynamic/_signatures.py:128: IndexError

tests/test_ext_autodoc/ goes from 4 failed, 222 passed to 4 failed, 223 passed. The four failures are present on unmodified master here as well — they are Python 3.14 import failures in test_autodoc_pep695_type_alias, test_final, test_overload3 and test_import_native_module_stubs, unrelated to this change. ruff check reports the same 9 pre-existing findings before and after; ruff format --check is clean.

AI disclosure

Claude (Opus 5) was used to locate the code, draft the change and the test, and write this description. I built the reproducer and ran the before/after builds myself, checked that the four suite failures predate the change by running the suite on a clean checkout, and confirmed the new test fails without the fix. Happy to answer questions on it.

_format_signatures reads signatures[0] defensively when emitting
autodoc-process-signature, then writes signatures[0] unconditionally with
whatever a handler returned. Data and type objects skip signature
extraction, so that list is empty for them and the write raises
IndexError, which is caught and logged as

  WARNING: error while formatting signature for mod.obj:
  list assignment index out of range [autodoc]

and the object is rendered without its docstring.

Use slice assignment, which stores the signature whether or not one was
already extracted.

Closes sphinx-doc#14576.
@SirHegel

Copy link
Copy Markdown
Author

Closing — this duplicates work that was already open. #14592 (9 Aug), #14607 (16 Aug) and #14616 (18 Aug) all touch the same lines with the same fix; #14592 is the earliest and came from hitting this in a real docs build.

Nothing here that those do not already cover — the only difference is that this used signatures[:1] = [...] rather than an if/else, which is the same behaviour written shorter.

Sorry for the noise. I filtered #14576 on having no assignee and no comments, and did not check whether a PR already referenced it.

@SirHegel SirHegel closed this Aug 20, 2026
@SirHegel
SirHegel deleted the append-signature-when-none-extracted branch August 20, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

autodoc: IndexError formatting signature for callable data object with annotated class variable

1 participant