Skip to content

Commit 85c8bce

Browse files
authored
gh-152912: Fix audit hook exception check in sys.addaudithook() (GH-152913)
1 parent bde526d commit 85c8bce

5 files changed

Lines changed: 23 additions & 4 deletions

File tree

Doc/c-api/sys.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ accessible to C code. They all work with the current interpreter thread's
433433
This function is safe to call before :c:func:`Py_Initialize`. When called
434434
after runtime initialization, existing audit hooks are notified and may
435435
silently abort the operation by raising an error subclassed from
436-
:class:`Exception` (other errors will not be silenced).
436+
:class:`RuntimeError` (other errors will not be silenced).
437437
438438
The hook function is always called with an :term:`attached thread state` by
439439
the Python interpreter that raised the event.
@@ -447,7 +447,7 @@ accessible to C code. They all work with the current interpreter thread's
447447
448448
If the interpreter is initialized, this function raises an auditing event
449449
``sys.addaudithook`` with no arguments. If any existing hooks raise an
450-
exception derived from :class:`Exception`, the new hook will not be
450+
exception derived from :class:`RuntimeError`, the new hook will not be
451451
added and the exception is cleared. As a result, callers cannot assume
452452
that their hook has been added unless they control all existing hooks.
453453
@@ -462,6 +462,11 @@ accessible to C code. They all work with the current interpreter thread's
462462
463463
.. versionadded:: 3.8
464464
465+
.. versionchanged:: 3.8.1
466+
467+
Exceptions derived from :class:`Exception` but not :class:`RuntimeError`
468+
are no longer suppressed.
469+
465470
466471
.. _processcontrol:
467472

Lib/test/audit-tests.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ def test_block_add_hook_baseexception():
109109
pass
110110

111111

112+
def test_block_add_hook_valueerror():
113+
# Non-RuntimeError exceptions (like ValueError) should propagate out
114+
with assertRaises(ValueError):
115+
with TestHook(
116+
raise_on_events="sys.addaudithook", exc_type=ValueError
117+
) as hook1:
118+
with TestHook() as hook2:
119+
pass
120+
121+
112122
def test_marshal():
113123
import marshal
114124
o = ("a", "b", "c", 1, 2, 3)

Lib/test/test_audit.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ def test_block_add_hook(self):
5858
def test_block_add_hook_baseexception(self):
5959
self.do_test("test_block_add_hook_baseexception")
6060

61+
def test_block_add_hook_valueerror(self):
62+
self.do_test("test_block_add_hook_valueerror")
63+
6164
def test_marshal(self):
6265
import_helper.import_module("marshal")
6366

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

Python/sysmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,8 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
527527

528528
/* Invoke existing audit hooks to allow them an opportunity to abort. */
529529
if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
530-
if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
531-
/* We do not report errors derived from Exception */
530+
if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
531+
/* We do not report errors derived from RuntimeError */
532532
_PyErr_Clear(tstate);
533533
Py_RETURN_NONE;
534534
}

0 commit comments

Comments
 (0)