mirror of
https://github.com/python/cpython.git
synced 2026-01-27 05:05:50 +00:00
gh-143547: Fix PyErr_FormatUnraisable() fallback (#143557)
Hold a strong reference to 'hook' while calling the default unraisable took to log hook failure. Fix test_sys.UnraisableHookTest: use the right decorator function to disable colors. Previously, tests were always skipped.
This commit is contained in:
parent
6d54b6ac7d
commit
39a2bcf949
@ -1350,7 +1350,7 @@ class SysModuleTest(unittest.TestCase):
|
||||
|
||||
|
||||
@test.support.cpython_only
|
||||
@force_not_colorized
|
||||
@test.support.force_not_colorized_test_class
|
||||
class UnraisableHookTest(unittest.TestCase):
|
||||
def test_original_unraisablehook(self):
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
@ -1492,6 +1492,7 @@ class UnraisableHookTest(unittest.TestCase):
|
||||
def test_custom_unraisablehook_fail(self):
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
from _testcapi import err_writeunraisable
|
||||
|
||||
def hook_func(*args):
|
||||
raise Exception("hook_func failed")
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
Fix :func:`sys.unraisablehook` when the hook raises an exception and changes
|
||||
:func:`sys.unraisablehook`: hold a strong reference to the old hook. Patch
|
||||
by Victor Stinner.
|
||||
@ -1656,6 +1656,7 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
||||
_Py_EnsureTstateNotNULL(tstate);
|
||||
|
||||
PyObject *err_msg = NULL;
|
||||
PyObject *hook = NULL;
|
||||
PyObject *exc_type, *exc_value, *exc_tb;
|
||||
_PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
|
||||
|
||||
@ -1700,7 +1701,6 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
||||
goto error;
|
||||
}
|
||||
|
||||
PyObject *hook;
|
||||
if (PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
|
||||
Py_DECREF(hook_args);
|
||||
err_msg_str = NULL;
|
||||
@ -1713,7 +1713,6 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
||||
}
|
||||
|
||||
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
err_msg_str = "Exception ignored in audit hook";
|
||||
obj = NULL;
|
||||
@ -1721,13 +1720,11 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
||||
}
|
||||
|
||||
if (hook == Py_None) {
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
goto default_hook;
|
||||
}
|
||||
|
||||
PyObject *res = PyObject_CallOneArg(hook, hook_args);
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
if (res != NULL) {
|
||||
Py_DECREF(res);
|
||||
@ -1757,6 +1754,7 @@ done:
|
||||
Py_XDECREF(exc_value);
|
||||
Py_XDECREF(exc_tb);
|
||||
Py_XDECREF(err_msg);
|
||||
Py_XDECREF(hook);
|
||||
_PyErr_Clear(tstate); /* Just in case */
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user