I've seen Launch an IPython shell on exception, but that doesn't help me here (testing on Python 2.7.1, Ubuntu 11.04). Consider the following example:
import wx
class Tester(object):
def __init__(self, innum):
print("innum: " +str(innum))
for x in xrange(innum,-1,-1):
tval = float(innum)/x
print(tval)
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Except Test")
self.btn = wx.Button(self, -1, "Click me")
self.btn.SetBackgroundColour(wx.NamedColour("orange"))
psizer = wx.BoxSizer(wx.HORIZONTAL)
psizer.Add(self.btn, 1, wx.EXPAND | wx.ALL, 20)
self.SetSizer(psizer)
self.SetSize((200,200))
self.btn.Bind(wx.EVT_BUTTON, self.runTest)
self.Layout()
def runTest(self, event):
t = Tester(3)
print(t)
if __name__ == '__main__':
runWx = True# False#
if not(runWx):
t = Tester(3)
print(t)
else:
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
If I set the runWx
to False
, so the program runs strictly from the command line, all is as expected:
$ python -m pdb test.py
> /tmp/test.py(1)<module>()
-> import wx
(Pdb) c
innum: 3
1.0
1.5
3.0
Traceback (most recent call last):
File "/usr/lib/python2.7/pdb.py", line 1314, in main
pdb._runscript(mainpyfile)
File "/usr/lib/python2.7/pdb.py", line 1233, in _runscript
self.run(statement)
File "/usr/lib/python2.7/bdb.py", line 387, in run
exec cmd in globals, locals
File "<string>", line 1, in <module>
File "test.py", line 1, in <module>
import wx
File "test.py", line 7, in __init__
tval = float(innum)/x
ZeroDivisionError: float division by zero
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /tmp/test.py(7)__init__()
-> tval = float(innum)/x
(Pdb) p x
0
(Pdb) q
Post mortem debugger finished. The test.py will be restarted
> /tmp/test.py(1)<module>()
-> import wx
(Pdb) q
... that is, when the exception is raised, pdb
raises a post mortem shell, I can inspect values, and exit the program.
But if runWx
is True
, as in the code, then I have to click the button on the GUI to raise an exception; and in that case, I get this:
$ python -m pdb test.py
> /tmp/test.py(1)<module>()
-> import wx
(Pdb) c
innum: 3
1.0
1.5
3.0
Traceback (most recent call last):
File "test.py", line 22, in runTest
t = Tester(3)
File "test.py", line 7, in __init__
tval = float(innum)/x
ZeroDivisionError: float division by zero
... that is - no pdb
shell is shown, instead the output terminal is simply blocking after printing the traceback (and in fact, you can click the button repeatedly, and repeatedly have the traceback printed in the terminal, while never dropping to the pdb
shell).
Is it possible to drop to a pdb
shell upon an unhandled exception raised from a wx
(or any) GUI event - and if so, how do I do it in the example above?