]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140530: fix a reference leak in an error path for `raise exc from cause` (#140908)
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Sun, 9 Nov 2025 12:41:08 +0000 (13:41 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Nov 2025 12:41:08 +0000 (13:41 +0100)
Fix a reference leak in `raise E from T` when `T` is an exception
subtype for which `T.__new__` does not return an exception instance.

Lib/test/test_raise.py
Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-12-47-38.gh-issue-140530.S934bp.rst [new file with mode: 0644]
Python/ceval.c

index dcf0753bc828f3f557745c1c1775be9edb2dd801..645ef291a58499342e650e3ff71bef52f77fb0aa 100644 (file)
@@ -186,18 +186,14 @@ class TestCause(unittest.TestCase):
             self.fail("No exception raised")
 
     def test_class_cause_nonexception_result(self):
-        class ConstructsNone(BaseException):
-            @classmethod
+        # See https://github.com/python/cpython/issues/140530.
+        class ConstructMortal(BaseException):
             def __new__(*args, **kwargs):
-                return None
-        try:
-            raise IndexError from ConstructsNone
-        except TypeError as e:
-            self.assertIn("should have returned an instance of BaseException", str(e))
-        except IndexError:
-            self.fail("Wrong kind of exception raised")
-        else:
-            self.fail("No exception raised")
+                return ["mortal value"]
+
+        msg = ".*should have returned an instance of BaseException.*"
+        with self.assertRaisesRegex(TypeError, msg):
+            raise IndexError from ConstructMortal
 
     def test_instance_cause(self):
         cause = KeyError()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-12-47-38.gh-issue-140530.S934bp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-12-47-38.gh-issue-140530.S934bp.rst
new file mode 100644 (file)
index 0000000..e3af493
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a reference leak when ``raise exc from cause`` fails. Patch by Bénédikt
+Tran.
index 7ca7ae48b5c88a2a2a9514748e037f8c3347a70c..43e8ee712065664d9fa9612095dbb117c83c96f2 100644 (file)
@@ -2148,6 +2148,7 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
                               "calling %R should have returned an instance of "
                               "BaseException, not %R",
                               cause, Py_TYPE(fixed_cause));
+                Py_DECREF(fixed_cause);
                 goto raise_error;
             }
             Py_DECREF(cause);