raise self.exc_type("saw event " + event)
-class TestFinalizeHook:
- """Used in the test_finalize_hooks function to ensure that hooks
- are correctly cleaned up, that they are notified about the cleanup,
- and are unable to prevent it.
- """
-
- def __init__(self):
- print("Created", id(self), file=sys.stdout, flush=True)
-
- def __call__(self, event, args):
- # Avoid recursion when we call id() below
- if event == "builtins.id":
- return
-
- print(event, id(self), file=sys.stdout, flush=True)
-
- if event == "cpython._PySys_ClearAuditHooks":
- raise RuntimeError("Should be ignored")
- elif event == "cpython.PyInterpreterState_Clear":
- raise RuntimeError("Should be ignored")
-
-
# Simple helpers, since we are not in unittest here
def assertEqual(x, y):
if x != y:
pass
-def test_finalize_hooks():
- sys.addaudithook(TestFinalizeHook())
-
-
def test_pickle():
import pickle
def test_block_add_hook_baseexception(self):
self.do_test("test_block_add_hook_baseexception")
- def test_finalize_hooks(self):
- returncode, events, stderr = self.run_python("test_finalize_hooks")
- if stderr:
- print(stderr, file=sys.stderr)
- if returncode:
- self.fail(stderr)
-
- firstId = events[0][2]
- self.assertSequenceEqual(
- [
- ("Created", " ", firstId),
- ("cpython._PySys_ClearAuditHooks", " ", firstId),
- ],
- events,
- )
-
def test_pickle(self):
support.import_module("pickle")
--- /dev/null
+Audit hooks are now cleared later during finalization to avoid missing events.
\ No newline at end of file
return result;
}
+static int _audit_hook_clear_count = 0;
+
static int _audit_hook(const char *event, PyObject *args, void *userdata)
{
+ assert(args && PyTuple_CheckExact(args));
if (strcmp(event, "_testembed.raise") == 0) {
PyErr_SetString(PyExc_RuntimeError, "Intentional error");
return -1;
return -1;
}
return 0;
+ } else if (strcmp(event, "cpython._PySys_ClearAuditHooks") == 0) {
+ _audit_hook_clear_count += 1;
}
return 0;
}
{
int result = _test_audit(42);
Py_Finalize();
+ if (_audit_hook_clear_count != 1) {
+ return 0x1000 | _audit_hook_clear_count;
+ }
return result;
}
_PyGC_CollectNoFail();
}
+ /* Clear all loghooks */
+ /* Both _PySys_Audit function and users still need PyObject, such as tuple.
+ Call _PySys_ClearAuditHooks when PyObject available. */
+ if (is_main_interp) {
+ _PySys_ClearAuditHooks(tstate);
+ }
+
_PyGC_Fini(tstate);
if (is_main_interp) {
*/
_PyGC_CollectIfEnabled();
- /* Clear all loghooks */
- _PySys_ClearAuditHooks(tstate);
-
/* Destroy all modules */
_PyImport_Cleanup(tstate);