Skip to content

Commit 7503201

Browse files
vstinnermiss-islington
authored andcommitted
[3.14] gh-143547: Fix PyErr_FormatUnraisable() fallback (GH-143557) (GH-143603)
gh-143547: Fix PyErr_FormatUnraisable() fallback (GH-143557) Hold a strong reference to 'hook' while calling the default unraisable took to log hook failure. (cherry picked from commit 1d0baf1) Co-authored-by: Victor Stinner <vstinner@python.org> (cherry picked from commit 39a2bcf)
1 parent a4a33ff commit 7503201

File tree

3 files changed

+6
-4
lines changed

3 files changed

+6
-4
lines changed

Lib/test/test_sys.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@ def hook_func(args):
14951495
def test_custom_unraisablehook_fail(self):
14961496
_testcapi = import_helper.import_module('_testcapi')
14971497
from _testcapi import err_writeunraisable
1498+
14981499
def hook_func(*args):
14991500
raise Exception("hook_func failed")
15001501

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :func:`sys.unraisablehook` when the hook raises an exception and changes
2+
:func:`sys.unraisablehook`: hold a strong reference to the old hook. Patch
3+
by Victor Stinner.

Python/errors.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,7 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
15931593
_Py_EnsureTstateNotNULL(tstate);
15941594

15951595
PyObject *err_msg = NULL;
1596+
PyObject *hook = NULL;
15961597
PyObject *exc_type, *exc_value, *exc_tb;
15971598
_PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
15981599

@@ -1637,7 +1638,6 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
16371638
goto error;
16381639
}
16391640

1640-
PyObject *hook;
16411641
if (_PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
16421642
Py_DECREF(hook_args);
16431643
err_msg_str = NULL;
@@ -1650,21 +1650,18 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
16501650
}
16511651

16521652
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
1653-
Py_DECREF(hook);
16541653
Py_DECREF(hook_args);
16551654
err_msg_str = "Exception ignored in audit hook";
16561655
obj = NULL;
16571656
goto error;
16581657
}
16591658

16601659
if (hook == Py_None) {
1661-
Py_DECREF(hook);
16621660
Py_DECREF(hook_args);
16631661
goto default_hook;
16641662
}
16651663

16661664
PyObject *res = PyObject_CallOneArg(hook, hook_args);
1667-
Py_DECREF(hook);
16681665
Py_DECREF(hook_args);
16691666
if (res != NULL) {
16701667
Py_DECREF(res);
@@ -1694,6 +1691,7 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
16941691
Py_XDECREF(exc_value);
16951692
Py_XDECREF(exc_tb);
16961693
Py_XDECREF(err_msg);
1694+
Py_XDECREF(hook);
16971695
_PyErr_Clear(tstate); /* Just in case */
16981696
}
16991697

0 commit comments

Comments
 (0)