-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix finalizing and atexit timing #6626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 184
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 1449
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 1454
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 168
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 435
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 3393
🏁 Script executed:
Repository: RustPython/RustPython
Length of output: 389
🌐 Web query:
CPython Py_FinalizeEx atexit exceptions handling unraisable hook💡 Result:
Short summary — how CPython handles exceptions during Py_FinalizeEx / atexit and the unraisable hook
Py_FinalizeEx runs Python-level shutdown which includes running atexit handlers. Exceptions raised in atexit handlers produce a printed traceback (to sys.stderr) and the last non-SystemExit exception raised is re-raised after all handlers have run. [1][2]
C-level exit handlers (Py_AtExit) are separate: they are called by Py_FinalizeEx but run after Python internal finalization; they must not call Python APIs. Py_AtExit handlers are for C code, not Python-level cleanup. [3]
sys.unraisablehook (added in Python 3.8) is the configurable hook used for "unraisable exceptions" (e.g., exceptions in del, weakref callbacks, GC callbacks). By default Python logs these to sys.stderr; you can override sys.unraisablehook to customize handling. [4]
Important caveat: some "unraisable" errors occur very late in interpreter finalization (after core modules like sys and stderr have been cleared). In that case the custom sys.unraisablehook cannot be called and the error may go unreported (PyErr_WriteUnraisable may be a no‑op if stderr/sys are gone). This limitation is documented and tracked in the issue thread that introduced sys.unraisablehook. [4][5]
Practical implications
Sources
[1] atexit — Exit handlers (Python docs).
[2] atexit behavior / examples (Python docs, PyMotW).
[3] Initialization, Finalization, and Threads / Py_AtExit (CPython C-API docs).
[4] Issue and PR discussion and docs for sys.unraisablehook (bpo-36829 / sys docs / Victor Stinner blog).
[5] Python tracker discussion about very-late unraisable exceptions during finalization.
Atexit exceptions are being suppressed during finalization, which differs from CPython's behavior.
RustPython sets the
finalizingflag at line 143, before callingatexit::_run_exitfuncs(vm)at line 146. This causes therun_unraisablecall in atexit handlers to return early and suppress exception reporting. CPython still prints atexit handler exceptions to stderr during finalization, making them visible for debugging. Consider either moving thefinalizingflag to after atexit completion, or adding a special case inrun_unraisableto allow atexit exceptions to bypass the finalization suppression.🤖 Prompt for AI Agents