Merge pull request #557 from campagnola/console-updates
Allow console stack to be set outside of exceptions
This commit is contained in:
commit
3ddba03d08
@ -53,6 +53,7 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
self.editor = editor
|
||||
self.multiline = None
|
||||
self.inCmd = False
|
||||
self.frames = [] # stack frames to access when an item in the stack list is selected
|
||||
|
||||
self.ui = template.Ui_Form()
|
||||
self.ui.setupUi(self)
|
||||
@ -133,14 +134,14 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
def globals(self):
|
||||
frame = self.currentFrame()
|
||||
if frame is not None and self.ui.runSelectedFrameCheck.isChecked():
|
||||
return self.currentFrame().tb_frame.f_globals
|
||||
return self.currentFrame().f_globals
|
||||
else:
|
||||
return self.localNamespace
|
||||
|
||||
def locals(self):
|
||||
frame = self.currentFrame()
|
||||
if frame is not None and self.ui.runSelectedFrameCheck.isChecked():
|
||||
return self.currentFrame().tb_frame.f_locals
|
||||
return self.currentFrame().f_locals
|
||||
else:
|
||||
return self.localNamespace
|
||||
|
||||
@ -149,10 +150,7 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
if self.currentTraceback is None:
|
||||
return None
|
||||
index = self.ui.exceptionStackList.currentRow()
|
||||
tb = self.currentTraceback
|
||||
for i in range(index):
|
||||
tb = tb.tb_next
|
||||
return tb
|
||||
return self.frames[index]
|
||||
|
||||
def execSingle(self, cmd):
|
||||
try:
|
||||
@ -171,7 +169,6 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
except:
|
||||
self.displayException()
|
||||
|
||||
|
||||
def execMulti(self, nextLine):
|
||||
#self.stdout.write(nextLine+"\n")
|
||||
if nextLine.strip() != '':
|
||||
@ -202,6 +199,10 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
self.multiline = None
|
||||
|
||||
def write(self, strn, html=False):
|
||||
isGuiThread = QtCore.QThread.currentThread() == QtCore.QCoreApplication.instance().thread()
|
||||
if not isGuiThread:
|
||||
self.stdout.write(strn)
|
||||
return
|
||||
self.output.moveCursor(QtGui.QTextCursor.End)
|
||||
if html:
|
||||
self.output.textCursor().insertHtml(strn)
|
||||
@ -293,14 +294,6 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
fileName = tb.tb_frame.f_code.co_filename
|
||||
subprocess.Popen(self.editor.format(fileName=fileName, lineNum=lineNum), shell=True)
|
||||
|
||||
|
||||
#def allExceptionsHandler(self, *args):
|
||||
#self.exceptionHandler(*args)
|
||||
|
||||
#def nextExceptionHandler(self, *args):
|
||||
#self.ui.catchNextExceptionBtn.setChecked(False)
|
||||
#self.exceptionHandler(*args)
|
||||
|
||||
def updateSysTrace(self):
|
||||
## Install or uninstall sys.settrace handler
|
||||
|
||||
@ -319,24 +312,72 @@ class ConsoleWidget(QtGui.QWidget):
|
||||
else:
|
||||
sys.settrace(self.systrace)
|
||||
|
||||
def exceptionHandler(self, excType, exc, tb):
|
||||
def exceptionHandler(self, excType, exc, tb, systrace=False):
|
||||
if self.ui.catchNextExceptionBtn.isChecked():
|
||||
self.ui.catchNextExceptionBtn.setChecked(False)
|
||||
elif not self.ui.catchAllExceptionsBtn.isChecked():
|
||||
return
|
||||
|
||||
self.ui.clearExceptionBtn.setEnabled(True)
|
||||
self.currentTraceback = tb
|
||||
|
||||
excMessage = ''.join(traceback.format_exception_only(excType, exc))
|
||||
self.ui.exceptionInfoLabel.setText(excMessage)
|
||||
|
||||
if systrace:
|
||||
# exceptions caught using systrace don't need the usual
|
||||
# call stack + traceback handling
|
||||
self.setStack(sys._getframe().f_back.f_back)
|
||||
else:
|
||||
self.setStack(frame=sys._getframe().f_back, tb=tb)
|
||||
|
||||
def setStack(self, frame=None, tb=None):
|
||||
"""Display a call stack and exception traceback.
|
||||
|
||||
This allows the user to probe the contents of any frame in the given stack.
|
||||
|
||||
*frame* may either be a Frame instance or None, in which case the current
|
||||
frame is retrieved from ``sys._getframe()``.
|
||||
|
||||
If *tb* is provided then the frames in the traceback will be appended to
|
||||
the end of the stack list. If *tb* is None, then sys.exc_info() will
|
||||
be checked instead.
|
||||
"""
|
||||
self.ui.clearExceptionBtn.setEnabled(True)
|
||||
|
||||
if frame is None:
|
||||
frame = sys._getframe().f_back
|
||||
|
||||
if tb is None:
|
||||
tb = sys.exc_info()[2]
|
||||
|
||||
self.ui.exceptionStackList.clear()
|
||||
self.frames = []
|
||||
|
||||
# Build stack up to this point
|
||||
for index, line in enumerate(traceback.extract_stack(frame)):
|
||||
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
||||
while frame is not None:
|
||||
self.frames.insert(0, frame)
|
||||
frame = frame.f_back
|
||||
|
||||
if tb is None:
|
||||
return
|
||||
|
||||
self.ui.exceptionStackList.addItem('-- exception caught here: --')
|
||||
item = self.ui.exceptionStackList.item(self.ui.exceptionStackList.count()-1)
|
||||
item.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
|
||||
self.frames.append(None)
|
||||
|
||||
# And finish the rest of the stack up to the exception
|
||||
for index, line in enumerate(traceback.extract_tb(tb)):
|
||||
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
||||
while tb is not None:
|
||||
self.frames.append(tb.tb_frame)
|
||||
tb = tb.tb_next
|
||||
|
||||
def systrace(self, frame, event, arg):
|
||||
if event == 'exception' and self.checkException(*arg):
|
||||
self.exceptionHandler(*arg)
|
||||
self.exceptionHandler(*arg, systrace=True)
|
||||
return self.systrace
|
||||
|
||||
def checkException(self, excType, exc, tb):
|
||||
|
@ -86,7 +86,10 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<property name="horizontalSpacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="6">
|
||||
@ -95,7 +98,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear Exception</string>
|
||||
<string>Clear Stack</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -149,7 +152,7 @@
|
||||
<item row="1" column="0" colspan="7">
|
||||
<widget class="QLabel" name="exceptionInfoLabel">
|
||||
<property name="text">
|
||||
<string>Exception Info</string>
|
||||
<string>Stack Trace</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'template.ui'
|
||||
#
|
||||
# Created: Fri May 02 18:55:28 2014
|
||||
# Created: Wed Apr 08 16:28:53 2015
|
||||
# by: PyQt4 UI code generator 4.10.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
@ -68,8 +68,9 @@ class Ui_Form(object):
|
||||
self.exceptionGroup = QtGui.QGroupBox(self.splitter)
|
||||
self.exceptionGroup.setObjectName(_fromUtf8("exceptionGroup"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.exceptionGroup)
|
||||
self.gridLayout_2.setSpacing(0)
|
||||
self.gridLayout_2.setContentsMargins(-1, 0, -1, 0)
|
||||
self.gridLayout_2.setHorizontalSpacing(2)
|
||||
self.gridLayout_2.setVerticalSpacing(0)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.clearExceptionBtn = QtGui.QPushButton(self.exceptionGroup)
|
||||
self.clearExceptionBtn.setEnabled(False)
|
||||
@ -116,12 +117,12 @@ class Ui_Form(object):
|
||||
self.historyBtn.setText(_translate("Form", "History..", None))
|
||||
self.exceptionBtn.setText(_translate("Form", "Exceptions..", None))
|
||||
self.exceptionGroup.setTitle(_translate("Form", "Exception Handling", None))
|
||||
self.clearExceptionBtn.setText(_translate("Form", "Clear Exception", None))
|
||||
self.clearExceptionBtn.setText(_translate("Form", "Clear Stack", None))
|
||||
self.catchAllExceptionsBtn.setText(_translate("Form", "Show All Exceptions", None))
|
||||
self.catchNextExceptionBtn.setText(_translate("Form", "Show Next Exception", None))
|
||||
self.onlyUncaughtCheck.setText(_translate("Form", "Only Uncaught Exceptions", None))
|
||||
self.runSelectedFrameCheck.setText(_translate("Form", "Run commands in selected stack frame", None))
|
||||
self.exceptionInfoLabel.setText(_translate("Form", "Exception Info", None))
|
||||
self.exceptionInfoLabel.setText(_translate("Form", "Stack Trace", None))
|
||||
self.label.setText(_translate("Form", "Filter (regex):", None))
|
||||
|
||||
from .CmdInput import CmdInput
|
||||
|
@ -100,7 +100,7 @@ class Ui_Form(object):
|
||||
self.catchNextExceptionBtn.setText(QtGui.QApplication.translate("Form", "Show Next Exception", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.onlyUncaughtCheck.setText(QtGui.QApplication.translate("Form", "Only Uncaught Exceptions", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.runSelectedFrameCheck.setText(QtGui.QApplication.translate("Form", "Run commands in selected stack frame", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.exceptionInfoLabel.setText(QtGui.QApplication.translate("Form", "Exception Info", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.clearExceptionBtn.setText(QtGui.QApplication.translate("Form", "Clear Exception", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.exceptionInfoLabel.setText(QtGui.QApplication.translate("Form", "Stack Trace", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.clearExceptionBtn.setText(QtGui.QApplication.translate("Form", "Clear Stack", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
from .CmdInput import CmdInput
|
||||
|
Loading…
Reference in New Issue
Block a user