diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 8be5bf8aa4f546..53bd369fabe21f 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -109,6 +109,16 @@ def test_block_add_hook_baseexception(): pass +def test_block_add_hook_valueerror(): + # Non-RuntimeError exceptions (like ValueError) should propagate out + with assertRaises(ValueError): + with TestHook( + raise_on_events="sys.addaudithook", exc_type=ValueError + ) as hook1: + with TestHook() as hook2: + pass + + def test_marshal(): import marshal o = ("a", "b", "c", 1, 2, 3) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index db4e1eb9999c1f..e9e546fdbfd6fb 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -58,6 +58,9 @@ def test_block_add_hook(self): def test_block_add_hook_baseexception(self): self.do_test("test_block_add_hook_baseexception") + def test_block_add_hook_valueerror(self): + self.do_test("test_block_add_hook_valueerror") + def test_marshal(self): import_helper.import_module("marshal") diff --git a/Misc/NEWS.d/next/Library/2026-07-03-02-11-00.gh-issue-152912.Mv3KpR.rst b/Misc/NEWS.d/next/Library/2026-07-03-02-11-00.gh-issue-152912.Mv3KpR.rst new file mode 100644 index 00000000000000..a4d7c4a9b0a294 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-03-02-11-00.gh-issue-152912.Mv3KpR.rst @@ -0,0 +1 @@ +``sys.addaudithook()`` now correctly suppresses only :exc:`RuntimeError` instead of all :exc:`Exception` subclasses when an existing audit hook raises during hook registration. Patch by Yeongu Kim. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index d9f7b9c449cfb9..3fe396fa440803 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -527,8 +527,8 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook) /* Invoke existing audit hooks to allow them an opportunity to abort. */ if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { - /* We do not report errors derived from Exception */ + if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) { + /* We do not report errors derived from RuntimeError */ _PyErr_Clear(tstate); Py_RETURN_NONE; }