Skip to content

馃悰 fix(docstring): survive a re-entrant docstring handler - #758

Merged
gaborbernat merged 1 commit into
tox-dev:mainfrom
gaborbernat:fix-750-reentrant-config-state
Aug 24, 2026
Merged

馃悰 fix(docstring): survive a re-entrant docstring handler#758
gaborbernat merged 1 commit into
tox-dev:mainfrom
gaborbernat:fix-750-reentrant-config-state

Conversation

@gaborbernat

Copy link
Copy Markdown
Member

Building the docs died with ExtensionError: Handler <function process_docstring ...> threw an exception (exception: 'Config' object has no attribute '_annotation_globals'), reported in #750 against 3.5-3.6. process_docstring hangs three values off the config for the formatting code to read and deletes them in a finally. That works until documenting one object starts documenting another before the first one finishes: the inner call deletes the attributes, and the outer call then raises on its own teardown, which is the error the reporter saw. On their version an autodoc directive sitting in a docstring was enough, because the throwaway parse that places :rtype: ran it. The reproducer below builds clean since #624 neutralized those directives.

A typehints_formatter that documents a nested object still re-enters the handler on main, and still aborts the build the same way. Rather than block re-entry, the teardown now puts back whatever it found: an inner call restores the outer call's values, and the outermost call clears them. Nesting turns into an ordinary save and restore, whatever the caller did to reach it. 馃攣

# conf.py
def setup(app):
    import demo
    from sphinx_autodoc_typehints import process_docstring

    def formatter(annotation, config):
        if annotation is int:
            process_docstring(app, "function", "demo.helper", demo.helper, None, ["Help."])
        return None

    app.config.typehints_formatter = formatter

process_docstring published three values on the config for the formatting
code to read, then deleted them on the way out. Documenting one object can
begin documenting another before the first finishes, through a
typehints_formatter that renders a nested object or, before tox-dev#624, through an
autodoc directive inside a docstring the rtype probe parsed. The inner call
deleted the attributes, the outer call then failed its own teardown, and
Sphinx aborted the build with "'Config' object has no attribute
'_annotation_globals'".

The teardown now restores whatever it found instead of deleting, so the
outer call gets its own state back and the innermost one clears it.

Closes tox-dev#750
@gaborbernat
gaborbernat force-pushed the fix-750-reentrant-config-state branch from 90d8635 to 1e8e1ac Compare August 24, 2026 14:37
@gaborbernat
gaborbernat merged commit 02dd58f into tox-dev:main Aug 24, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant