Repository navigation
gh-159283: Keep the propagating exception in PyObject_ClearManagedDict() - #159284
Open
christianaurichzm wants to merge 1 commit into
Open
christianaurichzm wants to merge 1 commit into
christianaurichzm wants to merge 1 commit into
Conversation
…gedDict() When an object whose __dict__ still pointed at its inline values was freed while an exception was propagating, a failed allocation while detaching the dict called PyErr_NoMemory(), which replaced that exception, and PyErr_FormatUnraisable() then cleared it. A debug build aborted in py_dealloc() and a release build went on with no exception set, which ended in SystemError. Save the current exception before detaching the dict and restore it afterwards.
christianaurichzm
requested review from
markshannon and
methane
as code owners
October 13, 2026 02:28
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #159283
PyObject_ClearManagedDict()runs when an object is freed. If the object's__dict__has been materialized but still points at the inline values, it callsdetach_dict_from_object(), which callsPyErr_NoMemory()whencopy_values()fails. When the object is freed while an exception is propagating, for example a temporary on the evaluation stack during unwinding, thatMemoryErrorreplaces the propagating exception, and thePyErr_FormatUnraisable()call that follows clears it. A debug build aborts inpy_dealloc(), and a release build goes on with no exception set and ends inSystemError('error return without exception set').This change saves the current exception with
PyErr_GetRaisedException()before detaching the dict and restores it afterwards. TheMemoryErroris still reported as unraisable, and the original exception keeps propagating. The extra calls are only on the path that detaches a materialized dict.The same code is in 3.14 and 3.15.
Verification
test_classaborts an unpatched debug build withFatal Python error: py_dealloc: Deallocator of type 'A' cleared the current exceptionand passes with the fix. The reproducer from the issue getsSystemErroron an unpatched release build andZeroDivisionErrorwith the fix.test_class,test_dict,test_capi.test_dict,test_descr,test_gc,test_exceptionsandtest_unittestpass on a debug build, and the new test passes with-R 3:3.