I think the answer is that this is not a PyQt “function”, but a consequence inherent in the design, which allows working with signals / slots (remember that the signal / slot connection passes through the C ++ layer as a).
This is ugly, but helps a little and ends your problem.
from PyQt4 import QtGui import time app = QtGui.QApplication([]) class exception_munger(object): def __init__(self): self.flag = True self.txt = '' self.type = None def indicate_fail(self,etype=None, txt=None): self.flag = False if txt is not None: self.txt = txt self.type = etype def reset(self): tmp_txt = self.txt tmp_type = self.type tmp_flag = self.flag self.flag = True self.txt = '' self.type = None return tmp_flag, tmp_type, tmp_txt class e_manager(): def __init__(self): self.old_hook = None def __enter__(self): em = exception_munger() def my_hook(type, value, tback): em.indicate_fail(type, value) sys.__excepthook__(type, value, tback) self.old_hook = sys.excepthook sys.excepthook = my_hook self.em = em return self def __exit__(self,*args,**kwargs): sys.excepthook = self.old_hook def mang_fac(): return e_manager() def assert_dec(original_fun): def new_fun(*args,**kwargs): with mang_fac() as mf: res = original_fun(*args, **kwargs) flag, etype, txt = mf.em.reset() if not flag: raise etype(txt) return res return new_fun @assert_dec def my_test_fun(): dialog = QtGui.QDialog() button = QtGui.QPushButton('I crash') layout = QtGui.QHBoxLayout() layout.addWidget(button) dialog.setLayout(layout) def crash(): time.sleep(1) raise Exception('Crash!') button.clicked.connect(crash) button.click() my_test_fun() print 'should not happen'
This will not print “should not be” and gives you something that can be caught using automatic tests (with the correct type of exception).
In [11]: Traceback (most recent call last): File "/tmp/ipython2-3426rwB.py", line 68, in crash Exception: Crash!
The stack trace goes up, but you can still read the first one that was printed.
source share