You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
test_tcl leaked [1, 1, 1] handles on AMD64 Windows Server 2025 Refleaks 3.x #161353
Yes, I confirm using git bisect that the regression was introduced by commit 9c0cfb1:
commit 9c0cfb141c236c902954841bb6cca407f86e1eeb (HEAD)
Author: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Date: Sun Nov 1 00:37:26 2026 -0700
gh-160176: Fix crash in tkinter on deeply nested or recursive lists (GH-160177)
Converting a nested list or tuple to a Tcl object now raises ValueError
above 1000 levels, the same limit _flatten() uses. Converting a deeply
nested Tcl list back to Python now raises RecursionError.
ANT-2026-7UKC5QED
The regression comes from the fact that the new test_returning_deeply_nested() test uses @support.run_with_limited_c_stack() decorator which runs the test in a new thread. The following test is enough to reproduce the issue:
Here's the chain: Tcl_CreateInterp() calls Tcl_InitSubsystems() (tclEvent.c:870), which calls TclInitNotifier() (tclEvent.c:1170), which calls TclpInitNotifier() (tclNotify.c:139), which executes the CreateEventW().
The Event is stored in thread-specific data (tsdPtr->event) and is only closed in TclpFinalizeNotifier() (tclWinNotify.c:171). But TclpFinalizeNotifier is only called from Tcl_FinalizeThread() or Tcl_Finalize() — Tcl_DeleteInterp() does not trigger notifier finalization. So if an embedder does Tcl_CreateInterp() + Tcl_DeleteInterp() without a subsequent Tcl_Finalize(), the Event handle leaks.
I confirm that calling Tcl_FinalizeThread() solves the handle leak.
Activity
hugovk commentedon Nov 4, 2026
I think this is caused by issue #160176 / PR #160177.
vstinner commentedon Nov 4, 2026
Yes, I confirm using git bisect that the regression was introduced by commit 9c0cfb1:
vstinner commentedon Nov 4, 2026
The regression comes from the fact that the new
test_returning_deeply_nested()test uses@support.run_with_limited_c_stack()decorator which runs the test in a new thread. The following test is enough to reproduce the issue:According to handle64.exe, the test creates ("leaks"?) a new "Event" handle.
vstinner commentedon Nov 4, 2026
Sadly, I still reproduce the leak if I modify _tkinter.create() to do just:
So the Windows event handle is not created by Python, but by Tcl.
vstinner commentedon Nov 4, 2026
Analyze of Claude Code on tcl9.0.4 source code:
I confirm that calling Tcl_FinalizeThread() solves the handle leak.
Tcl_FinalizeThread() => TclFinalizeNotifier() => Tcl_FinalizeNotifier() => TclpFinalizeNotifier() =>
CloseHandle(tsdPtr->event).vstinner commentedon Nov 4, 2026
I created #161368 to fix the test_tcl handle leak on Windows.
gh-161353: Fix handle leak in test_tcl (#161368)