https://github.com/python/cpython/commit/85c8bcee6780bd7e6730fe3550e9b65bbf62ff56
commit: 85c8bcee6780bd7e6730fe3550e9b65bbf62ff56
branch: main
author: k00shi <[email protected]>
committer: zooba <[email protected]>
date: 2026-07-27T19:35:40Z
summary:
gh-152912: Fix audit hook exception check in sys.addaudithook() (GH-152913)
files:
A Misc/NEWS.d/next/Library/2026-07-03-02-11-00.gh-issue-152912.Mv3KpR.rst
M Doc/c-api/sys.rst
M Lib/test/audit-tests.py
M Lib/test/test_audit.py
M Python/sysmodule.c
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index ee73c1c8adaa7b3..0a446f86e22eaf6 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -433,7 +433,7 @@ accessible to C code. They all work with the current
interpreter thread's
This function is safe to call before :c:func:`Py_Initialize`. When called
after runtime initialization, existing audit hooks are notified and may
silently abort the operation by raising an error subclassed from
- :class:`Exception` (other errors will not be silenced).
+ :class:`RuntimeError` (other errors will not be silenced).
The hook function is always called with an :term:`attached thread state` by
the Python interpreter that raised the event.
@@ -447,7 +447,7 @@ accessible to C code. They all work with the current
interpreter thread's
If the interpreter is initialized, this function raises an auditing event
``sys.addaudithook`` with no arguments. If any existing hooks raise an
- exception derived from :class:`Exception`, the new hook will not be
+ exception derived from :class:`RuntimeError`, the new hook will not be
added and the exception is cleared. As a result, callers cannot assume
that their hook has been added unless they control all existing hooks.
@@ -462,6 +462,11 @@ accessible to C code. They all work with the current
interpreter thread's
.. versionadded:: 3.8
+ .. versionchanged:: 3.8.1
+
+ Exceptions derived from :class:`Exception` but not :class:`RuntimeError`
+ are no longer suppressed.
+
.. _processcontrol:
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index 8be5bf8aa4f5469..53bd369fabe21f7 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 db4e1eb9999c1fa..e9e546fdbfd6fbe 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 000000000000000..a4d7c4a9b0a2948
--- /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 9442472b53abbe1..1e6e914b066bc5c 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;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]