Skip to content

Commit e7dccf0

Browse files
gpsheadvstinner
andauthored
[3.15] gh-161353: Fix handle leak in test_tcl (GH-161368) (#161650)
Fix handle leaks in test_tcl when the test is run with -R 3:3. Call explicitly Tcl_FinalizeThread() in test_returning_deeply_nested() to clean up explicitly per-thread state. The test is run in a thread because of the @run_with_limited_c_stack() decorator. On Windows, Tcl_CreateInterp() creates an event in the Tcl notifier implementation. The event is stored in per-thread state which is only cleaned up at exit. Add the private _tkinter._finalize_thread() function. (cherry picked from commit 2781ffe) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent c632048 commit e7dccf0

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

‎Lib/test/test_tcl.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ def test_returning_deeply_nested(self):
595595
interp.eval('set x a; for {set i 0} {$i < %d} {incr i} {set x [list $x]}'
596596
% support.exceeds_recursion_limit())
597597
self.assertRaises(RecursionError, interp.getvar, 'x')
598+
interp = None
599+
600+
# gh-161353: Clean up explicitly per-thread state to avoid leaking an
601+
# event handle on Windows when test_tcl is run with -R 3:3 option.
602+
_tkinter._finalize_thread()
598603

599604
def test_setvar_evil(self):
600605
# gh-161388

‎Modules/_tkinter.c‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3399,6 +3399,20 @@ _tkinter_getbusywaitinterval_impl(PyObject *module)
33993399
return Tkinter_busywaitinterval;
34003400
}
34013401

3402+
/*[clinic input]
3403+
_tkinter._finalize_thread
3404+
3405+
Clean up per-thread state.
3406+
[clinic start generated code]*/
3407+
3408+
static PyObject *
3409+
_tkinter__finalize_thread_impl(PyObject *module)
3410+
/*[clinic end generated code: output=4ed0d3be4d1f8de8 input=ea68096ee9b83d23]*/
3411+
{
3412+
Tcl_FinalizeThread();
3413+
Py_RETURN_NONE;
3414+
}
3415+
34023416
#include "clinic/_tkinter.c.h"
34033417

34043418
static PyMethodDef Tktt_methods[] =
@@ -3490,6 +3504,7 @@ static PyMethodDef moduleMethods[] =
34903504
_TKINTER_CREATE_METHODDEF
34913505
_TKINTER_SETBUSYWAITINTERVAL_METHODDEF
34923506
_TKINTER_GETBUSYWAITINTERVAL_METHODDEF
3507+
_TKINTER__FINALIZE_THREAD_METHODDEF
34933508
{NULL, NULL}
34943509
};
34953510

‎Modules/clinic/_tkinter.c.h‎

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)