From e3b2d4d7c6d6bf02ce12d810cd34427142c904ce Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 31 Oct 2025 17:49:19 +0000 Subject: [PATCH 1/2] Commit --- Lib/test/test_audit.py | 8 ++++++++ .../2025-10-31-17-47-44.gh-issue-140860.hexT7T.rst | 2 ++ Python/pylifecycle.c | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-17-47-44.gh-issue-140860.hexT7T.rst diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index db4e1eb9999c1f..6ec6c7fb436b98 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -289,6 +289,14 @@ def test_time_fail(self): self.assertNotEqual(returncode, 0) self.assertIn('hook failed', stderr.splitlines()[-1]) + def test_time_leak(self): + import sys + import time # Leaks struct_time_type + + hook = lambda a, b: None + sys.addaudithook(hook) + t = time.localtime() + def test_sys_monitoring_register_callback(self): returncode, events, stderr = self.run_python("test_sys_monitoring_register_callback") if returncode: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-17-47-44.gh-issue-140860.hexT7T.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-17-47-44.gh-issue-140860.hexT7T.rst new file mode 100644 index 00000000000000..0a91f4033cf9bb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-17-47-44.gh-issue-140860.hexT7T.rst @@ -0,0 +1,2 @@ +Fix memory leak where modules that create types during initialization +leak those types when audit hooks are active. diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8fcb31cfd12299..7da87b9e928e76 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2251,6 +2251,11 @@ _Py_Finalize(_PyRuntimeState *runtime) */ PyGC_Collect(); + /* Clear audit hooks before destroying modules to avoid reference cycles */ + if (_Py_IsMainInterpreter(tstate->interp)) { + Py_CLEAR(tstate->interp->audit_hooks); + } + /* Destroy all modules */ _PyImport_FiniExternal(tstate->interp); finalize_modules(tstate); From db2f997a5d548977aa31266742d76a987918fb91 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 31 Oct 2025 22:54:05 +0000 Subject: [PATCH 2/2] Commit --- Python/pylifecycle.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7da87b9e928e76..2e2fc499379ba5 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2252,9 +2252,7 @@ _Py_Finalize(_PyRuntimeState *runtime) PyGC_Collect(); /* Clear audit hooks before destroying modules to avoid reference cycles */ - if (_Py_IsMainInterpreter(tstate->interp)) { - Py_CLEAR(tstate->interp->audit_hooks); - } + Py_CLEAR(tstate->interp->audit_hooks); /* Destroy all modules */ _PyImport_FiniExternal(tstate->interp);