[3.14] gh-140530: fix a reference leak in an error path for raise exc from cause (GH-140908) (#141282)

gh-140530: fix a reference leak in an error path for `raise exc from cause` (GH-140908)

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.
(cherry picked from commit 0c77e7c23b)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2025-11-09 17:04:26 +01:00 committed by GitHub
parent cb458715a6
commit d7aace78e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 10 additions and 11 deletions

View file

@ -186,18 +186,14 @@ def test_class_cause(self):
self.fail("No exception raised") self.fail("No exception raised")
def test_class_cause_nonexception_result(self): def test_class_cause_nonexception_result(self):
class ConstructsNone(BaseException): # See https://github.com/python/cpython/issues/140530.
@classmethod class ConstructMortal(BaseException):
def __new__(*args, **kwargs): def __new__(*args, **kwargs):
return None return ["mortal value"]
try:
raise IndexError from ConstructsNone msg = ".*should have returned an instance of BaseException.*"
except TypeError as e: with self.assertRaisesRegex(TypeError, msg):
self.assertIn("should have returned an instance of BaseException", str(e)) raise IndexError from ConstructMortal
except IndexError:
self.fail("Wrong kind of exception raised")
else:
self.fail("No exception raised")
def test_instance_cause(self): def test_instance_cause(self):
cause = KeyError() cause = KeyError()

View file

@ -0,0 +1,2 @@
Fix a reference leak when ``raise exc from cause`` fails. Patch by Bénédikt
Tran.

View file

@ -2108,6 +2108,7 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
"calling %R should have returned an instance of " "calling %R should have returned an instance of "
"BaseException, not %R", "BaseException, not %R",
cause, Py_TYPE(fixed_cause)); cause, Py_TYPE(fixed_cause));
Py_DECREF(fixed_cause);
goto raise_error; goto raise_error;
} }
Py_DECREF(cause); Py_DECREF(cause);