From 8242da90ac593792c9a4b174c58e4d83dc2e252c Mon Sep 17 00:00:00 2001 From: abhi210 <27881020+Abhi210@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:21:12 +0530 Subject: [PATCH] BUG: Fixe dealloc clears the in-flight exception in subtype_dealloc --- .../2026-07-11-14-39-38.gh-issue-151763.nlYxAk.rst | 2 ++ Objects/typeobject.c | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-11-14-39-38.gh-issue-151763.nlYxAk.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-11-14-39-38.gh-issue-151763.nlYxAk.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-11-14-39-38.gh-issue-151763.nlYxAk.rst new file mode 100644 index 000000000000000..4d54c2b82da6cbc --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-11-14-39-38.gh-issue-151763.nlYxAk.rst @@ -0,0 +1,2 @@ +Fixed a bug in free-threaded builds where the active exception could be +unexpectedly cleared during subtype deallocation in ``subtype_dealloc()``. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b77f3e3bce54551..c66f245bdf329ab 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2833,6 +2833,13 @@ subtype_dealloc(PyObject *self) } } + /* Save the current exception: clear_slots() and the dict/base-dealloc + below decref arbitrary attribute values, which may clear + tstate->current_exception (gh-89373). Mirroring slot_tp_finalize(). */ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *exc = _PyErr_GetRaisedException(tstate); /* preserve in-flight exception */ + + /* Clear slots up to the nearest base with a different tp_dealloc */ base = type; while ((basedealloc = base->tp_dealloc) == subtype_dealloc) { @@ -2882,6 +2889,9 @@ subtype_dealloc(PyObject *self) if (type_needs_decref) { _Py_DECREF_TYPE(type); } + + /* Restore the saved exception (see save above). */ + _PyErr_SetRaisedException(tstate, exc); } static PyTypeObject *solid_base(PyTypeObject *type);