Files
h3n3-jmwright-CQ-Editor/cq_editor/widgets/traceback_viewer.py
2023-10-11 12:11:37 -05:00

90 lines
2.8 KiB
Python

from traceback import extract_tb, format_exception_only
from PySide6.QtWidgets import QWidget, QTreeWidget, QTreeWidgetItem, QLabel
from PySide6.QtGui import QAction
from PySide6.QtCore import Qt, Slot as pyqtSlot, Signal as pyqtSignal
from ..mixins import ComponentMixin
from ..utils import layout
class TracebackTree(QTreeWidget):
name = "Traceback Viewer"
def __init__(self, parent):
super(TracebackTree, self).__init__(parent)
self.setHeaderHidden(False)
self.setItemsExpandable(False)
self.setRootIsDecorated(False)
self.setContextMenuPolicy(Qt.ActionsContextMenu)
self.setColumnCount(3)
self.setHeaderLabels(["File", "Line", "Code"])
self.root = self.invisibleRootItem()
class TracebackPane(QWidget, ComponentMixin):
sigHighlightLine = pyqtSignal(int)
def __init__(self, parent):
super(TracebackPane, self).__init__(parent)
self.tree = TracebackTree(self)
self.current_exception = QLabel(self)
self.current_exception.setStyleSheet("QLabel {color : red; }")
layout(self, (self.current_exception, self.tree), self)
self.tree.currentItemChanged.connect(self.handleSelection)
@pyqtSlot(object, str)
def addTraceback(self, exc_info, code):
self.tree.clear()
if exc_info:
t, exc, tb = exc_info
root = self.tree.root
code = code.splitlines()
tb = [
t for t in extract_tb(tb) if "<string>" in t.filename
] # ignore highest frames (debug, exec)
for el in tb:
# workaround of the traceback module
if el.line == "":
line = code[el.lineno - 1].strip()
else:
line = el.line
root.addChild(QTreeWidgetItem([el.filename, str(el.lineno), line]))
exc_name = t.__name__
exc_msg = str(exc)
exc_msg = exc_msg.replace("<", "&lt;").replace(">", "&gt;") # replace <>
self.current_exception.setText("<b>{}</b>: {}".format(exc_name, exc_msg))
# handle the special case of a SyntaxError
if t is SyntaxError:
root.addChild(
QTreeWidgetItem(
[
exc.filename,
str(exc.lineno),
exc.text.strip() if exc.text else "",
]
)
)
else:
self.current_exception.setText("")
@pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
def handleSelection(self, item, *args):
if item:
f, line = item.data(0, 0), int(item.data(1, 0))
if "<string>" in f:
self.sigHighlightLine.emit(line)