diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-20-00-00-00.gh-issue-159739.da0f04.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-20-00-00-00.gh-issue-159739.da0f04.rst new file mode 100644 index 000000000000000..386eb5535b70252 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-20-00-00-00.gh-issue-159739.da0f04.rst @@ -0,0 +1,2 @@ +Fix reference leaks when free-threaded garbage collection aborts early because +of an allocation error. diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 264afeebd54f896..e8ed866312c94bf 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -2123,6 +2123,7 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state, int err = gc_mark_alive_from_roots(interp, state); if (err < 0) { _PyEval_StartTheWorld(interp); + cleanup_worklist(&state->objs_to_decref); PyErr_NoMemory(); return; } @@ -2133,6 +2134,9 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state, int err = deduce_unreachable_heap(interp, state); if (err < 0) { _PyEval_StartTheWorld(interp); + cleanup_worklist(&state->unreachable); + cleanup_worklist(&state->legacy_finalizers); + cleanup_worklist(&state->objs_to_decref); PyErr_NoMemory(); return; }