From 7f79179f1fd12fc7fac62f4ef1120e23a45eda33 Mon Sep 17 00:00:00 2001 From: Christian Aurich Zanettini Martins Date: Tue, 13 Oct 2026 03:24:00 -0300 Subject: [PATCH 1/2] gh-159294: Fix crash when creating an ExceptionGroup fails with MemoryError BaseExceptionGroup_new() passed the result of BaseException_new() to PyBaseExceptionGroupObject_CAST() before checking it for NULL. The cast asserts the type of its argument, so a debug build dereferenced NULL instead of raising MemoryError. --- Lib/test/test_exception_group.py | 10 ++++++++++ .../2026-10-13-06-23-56.gh-issue-159294.9LTsNA.rst | 3 +++ Objects/exceptions.c | 6 +++--- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-06-23-56.gh-issue-159294.9LTsNA.rst diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index f79bfa4ae2d322..212a9d144ef4a2 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,6 +1,7 @@ import collections import types import unittest +from test import support from test.support import (skip_emscripten_stack_overflow, skip_wasi_stack_overflow, run_with_limited_c_stack, exceeds_recursion_limit) @@ -130,6 +131,15 @@ class MyBEG(BaseExceptionGroup): type(MyBEG("eg", [ValueError(12), KeyboardInterrupt(42)])), MyBEG) + @support.nomemtest + def test_no_memory(self): + import _testcapi + # A tuple of exceptions is not copied, so the first allocation + # is the one of the exception group itself. + excs = (ValueError(1),) + with self.assertRaises(MemoryError): + _testcapi.call_with_nomemory(0, 0, ExceptionGroup, "eg", excs) + class StrAndReprTests(unittest.TestCase): def test_ExceptionGroup(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-06-23-56.gh-issue-159294.9LTsNA.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-06-23-56.gh-issue-159294.9LTsNA.rst new file mode 100644 index 00000000000000..9504f1f753cbec --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-06-23-56.gh-issue-159294.9LTsNA.rst @@ -0,0 +1,3 @@ +Fix a crash in a debug build when creating an :exc:`ExceptionGroup` or +:exc:`BaseExceptionGroup` fails with :exc:`MemoryError`. Patch by Christian +Aurich Zanettini Martins. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 781b5142ec326e..a45d921ca8de66 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -974,11 +974,11 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds) */ cls = (PyTypeObject*)PyExc_BaseExceptionGroup; } - PyBaseExceptionGroupObject *self = - PyBaseExceptionGroupObject_CAST(BaseException_new(cls, args, kwds)); - if (!self) { + PyObject *op = BaseException_new(cls, args, kwds); + if (!op) { goto error; } + PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op); self->msg = Py_NewRef(message); self->excs = exceptions; From bc1e578922909df284ff4049ef2bb13464eefbc1 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 23 Oct 2026 20:31:33 +0100 Subject: [PATCH 2/2] Nit: deduplicate import --- Lib/test/test_exception_group.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 212a9d144ef4a2..ec3b346a8db448 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,10 +1,9 @@ import collections import types import unittest -from test import support from test.support import (skip_emscripten_stack_overflow, skip_wasi_stack_overflow, run_with_limited_c_stack, - exceeds_recursion_limit) + exceeds_recursion_limit, nomemtest) class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): @@ -131,7 +130,7 @@ class MyBEG(BaseExceptionGroup): type(MyBEG("eg", [ValueError(12), KeyboardInterrupt(42)])), MyBEG) - @support.nomemtest + @nomemtest def test_no_memory(self): import _testcapi # A tuple of exceptions is not copied, so the first allocation