This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: wait_variable hangs at exit
Type: behavior Stage: test needed
Components: Tkinter Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: loewis Nosy List: ajaksu2, asvetlov, gpolo, loewis, reowen, terry.reedy
Priority: normal Keywords: patch

Created on 2004-06-23 23:07 by reowen, last changed 2022-04-11 14:56 by admin.

Files
File name Uploaded Description Edit
WaitTest.py reowen, 2004-06-23 23:07 demo of wait_variable bug
issue978604.diff gpolo, 2009-03-31 21:40 review
Messages (8)
msg21265 - (view) Author: Russell Owen (reowen) Date: 2004-06-23 23:07
If code is waiting on a wait_variable at program exit then the program never fully exits. The command prompt never returns and the process doesn't seem to be doing much of anything (i.e. no heavy CPU usage). ctrl-C has no effect.

I have found that binding to <Detroy> does work around the problem.

I saw this using a unix/X11 build of Python 2.3.4 on MacOS X 10.3.4 and also the standard Python 2.3 framework build included with MacOS X 10.3.

The attached file gives a good example. To see the problem, execute the script and then close the root window before the script finishes (you have 10 seconds).
msg82060 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2009-02-14 13:59
Confirmed on Linux (closing after 'script 2'):

trunk-py$ ./python WaitTest.py
script 0
script 1
script 2
invalid command name "137221876callit"
    while executing
"137221876callit"
    ("after" script)
msg84896 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-03-31 20:54
You can also reproduce it with a shorter test that doesn't need any
interaction:

import Tkinter

root = Tkinter.Tk()
waitvar = Tkinter.BooleanVar()

root.after(50, lambda: waitvar.set(True))
root.after(10, root.destroy)
root.wait_variable(waitvar)

root.mainloop()

Verifying.
msg84921 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-03-31 21:40
Patch attached, but didn't test it at all. This is a trick so it doesn't
get committed without a test (hopefully) :)
msg84944 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-03-31 23:11
Using this patch I noticed two problems appeared when running WaitTest.py

1) Closing the window results in: "_tkinter.TclError: can't invoke
"tkwait" command:  application has been destroyed" which I'm not
considering as a bug, maybe the user can get confused about this but if
the application were doing something like WaitTest.py does then it
should also be aware that this could happen.

2) Pressing Ctrl-c hits a different problem, causing ::tkerror to be
called, which I'm considering a bug that I still have to check.
msg84959 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-04-01 02:06
Ah.. number 2 is problematic. Before continuing lets reduce the previous
WaitTest.py to this (which shows the same problems):

import Tkinter

root = Tkinter.Tk()
waitVar = Tkinter.BooleanVar()

root.after(3000, lambda: waitVar.set(True))
root.wait_variable(waitVar)

When you run this, it will schedule the call to this lambda to happen 3
seconds later, and will block on the wait_variable call. Now suppose you
hit Ctrl-c while you are stuck into a Tcl_EvalObjv call (Tcl_EvalObjv
will end up being called after invoking wait_variable). Python will not
notice this Ctrl-c for now (we are on Tcl land now), but eventually the
event you scheduled earlier is fired. PythonCmd is called to handle it,
which will then call the anonymous func, but since you pressed Ctrl-c it
will return NULL and PythonCmd will call PythonCmd_Error to handle it.
PythonCmd_Error sets errInCmd to 1, saves the exception and returns an
TCL_ERROR indicator, this causes tkerror to be called. tkerror is a
function created in Tkinter.py, which does nothing so that previous
saved exception is not used. Next what happens is that the lambda
function didn't execute, the tk variable didn't change and you are still
blocked on wait_variable (this situation seems normal to me).

So what I did here, and I'm not sure if it would be accepted or not, was
create a new function in _tkinter.c called Tkinter_PrintError
(accessible through _tkinter._print_error) that restores the saved
exception and prints it. Now you might ask why not raise it instead ?
Martin that is on the nosy list will agree with me, I think. Raising an
error at this point will cause an Tk dialog to popup and it won't
contain a proper traceback (if done this way I did), which is annoying.

Note that even though PythonCmd_Error set errInCmd to 1, it was never
used because the mainloop wasn't running (it also wouldn't make much
difference to put a root.mainloop() after wait_variable since we would
be blocked before the mainloop started).
msg139198 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2011-06-26 19:21
In 3.2, winxp, (with Tkinter => tkinter), I get
invalid command name "12277720callit"
    while executing
"12277720callit"
    ("after" script)
and no new prompt and ^C ineffective. Had to kill command window.
With IDLE, get nothing and have to kill with Task Manager.
So confirmed for 3.x.
msg409177 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2021-12-26 00:32
Confirmed on Python 3.11.0a3+, assuming older versions also affected. This issue has different versions of tests to confirm it, but I think not in a test suite-friendly format yet.

There's also a patch and detailed analysis by gpolo indicating that it might need editing _tkinter.c to handle fallout from his proposed Python-side patch.
History
Date User Action Args
2022-04-11 14:56:05adminsetgithub: 40440
2021-12-26 00:32:27ajaksu2setmessages: + msg409177
versions: + Python 3.9, Python 3.10, Python 3.11, - Python 2.7, Python 3.2, Python 3.3
2012-03-21 17:09:44asvetlovsetnosy: + asvetlov
2011-06-26 19:21:15terry.reedysetnosy: + terry.reedy

messages: + msg139198
versions: + Python 3.2, Python 3.3, - Python 2.6, Python 3.1
2009-04-01 02:06:56gpolosetmessages: + msg84959
2009-03-31 23:11:22gpolosetmessages: + msg84944
2009-03-31 21:40:09gpolosetfiles: + issue978604.diff
keywords: + patch
messages: + msg84921
2009-03-31 20:54:22gpolosetnosy: + gpolo

messages: + msg84896
versions: + Python 3.1, Python 2.7
2009-02-14 13:59:11ajaksu2setnosy: + ajaksu2
stage: test needed
type: behavior
messages: + msg82060
versions: + Python 2.6, - Python 2.3
2004-06-23 23:07:12reowencreate