[Python-bugs-list] [ python-Bugs-639266 ] Tkinter sliently discards all Tcl errors
noreply@sourceforge.net
noreply@sourceforge.net
Wed, 11 Dec 2002 01:05:55 -0800
Bugs item #639266, was opened at 2002-11-16 07:35
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=639266&group_id=5470
Category: Tkinter
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Internet Discovery (idiscovery)
Assigned to: Nobody/Anonymous (nobody)
Summary: Tkinter sliently discards all Tcl errors
Initial Comment:
Tkinter silently discards all Tcl errors. Athough this may make Tkinter programs
appear robust, it violates the fundamental principle that erros should be raised
and dealt with.
In Tkinter.py is the line
self.tk.createcommand('tkerror', _tkerror)
where _tkerror is defined as
def _tkerror(err):
"""Internal function."""
pass
This disables all uses of the tcl procedure bgerror from signalling
background errors to the user, including I assume any errors
generated in after_idle.
----------------------------------------------------------------------
>Comment By: Internet Discovery (idiscovery)
Date: 2002-12-11 09:05
Message:
Logged In: YES
user_id=33229
What possible reason can you give to ever drop errors silently?
One example is in the Python distribution that I asked you about
over a year ago: Demo/tix/tixwidgets.py
----------------------------------------------------------------------
Comment By: Martin v. Löwis (loewis)
Date: 2002-11-19 22:56
Message:
Logged In: YES
user_id=21627
idiscovery, I still would like to see an example that
demonstrates that problem.
----------------------------------------------------------------------
Comment By: Internet Discovery (idiscovery)
Date: 2002-11-19 21:27
Message:
Logged In: YES
user_id=33229
That's right: Tkinter silently discards all background Tcl
errors.
All errors from Tcl are silenced by def _tkerror(err): pass
So Tkinter users will never see any errors that come from
any bugs in Tcl, Tk or its extensions, including of course
errors that may only show up under Python.
The proposed solution for this problem is simply to
remove the createcomand / def _tkerror. I see no possible
reason for it to be in there, and it violates the
fundamental principle that errors should be raised and dealt
with.
Although Tkinter behaved that way since the beginning, the
change takes backwards compatibility into account because
it serves no good purpose that I know of to begin with. At
worst buried bugs will become visible and can be dealt with.
----------------------------------------------------------------------
Comment By: Martin v. Löwis (loewis)
Date: 2002-11-17 21:03
Message:
Logged In: YES
user_id=21627
It is not the case that Tkinter silently discards all Python
errors. In fact, I believe it never discards any Python
error silently. Can you provide an example that demonstrates
otherwise?
----------------------------------------------------------------------
Comment By: Internet Discovery (idiscovery)
Date: 2002-11-17 19:57
Message:
Logged In: YES
user_id=33229
But why is Tkinter silencing all Tk (Tcl or Python) errors in the first place?
I know I can subclass Tk, but _tkerror is clearly billed as an internal function,
and the only purpose of it is to disable Tcl's bgerror reporting. This lets
serious bugs go undetected.
----------------------------------------------------------------------
Comment By: Jeff Epler (jepler)
Date: 2002-11-17 15:39
Message:
Logged In: YES
user_id=2772
You could create a subclass of Tk that creates a different
'tkerror' command.
Anyway, CallWrapper (used when a function is passed to
functions like .after_idle()) calls
widget._report_exception, which calls
Tk.report_callback_exception. So you can override this
function too.
Neither of these things require changing Tkinter.py.
I don't seem to be permitted to attach a file, so I'm forced
to paste the code.
import Tkinter as _Tkinter
class Tk(_Tkinter.Tk):
def __init__(self, *args, **kw):
_Tkinter.Tk.__init__(self, *args, **kw)
self.tk.createcommand('tkerror', self.tkerror)
def report_callback_exception(self, exc, val, tb):
print "callback exception", exc
def tkerror(self, *args):
print "tkerror", args
if __name__ == '__main__':
w = Tk()
w.after_idle(lambda: 1/0)
_Tkinter.Button(w, command="expr 1/0").pack()
w.mainloop()
----------------------------------------------------------------------
Comment By: Martin v. Löwis (loewis)
Date: 2002-11-16 09:33
Message:
Logged In: YES
user_id=21627
The qualification "silently discards all Tcl errors" is definitely
incorrect:
>>> Tkinter.Label(foo="bar")
Traceback (most recent call last):
File "<pyshell#1>", line 1, in ?
Tkinter.Label(foo="bar")
File "E:\Python22\lib\lib-tk\Tkinter.py", line 2261, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "E:\Python22\lib\lib-tk\Tkinter.py", line 1756, in __init__
self.tk.call(
TclError: unknown option "-foo"
Instead, it would be more correct to say that all background
errors are discarded.
Can you provide a script that demonstrates this problem?
(i.e. one which behaves differently if the createcommand is
removed from Tkinter.py)
Can you propose a solution for this problem? Please take
into account that Tkinter behaved that way since the
beginning, so any change must take backwards compatibility
into account.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=639266&group_id=5470