src/eric7/UI/PythonDisViewer.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
--- a/src/eric7/UI/PythonDisViewer.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/UI/PythonDisViewer.py	Wed Jul 13 14:55:47 2022 +0200
@@ -16,9 +16,7 @@
 
 from PyQt6.QtCore import pyqtSlot, Qt, QTimer
 from PyQt6.QtGui import QBrush
-from PyQt6.QtWidgets import (
-    QTreeWidgetItem, QAbstractItemView, QWidget, QMenu
-)
+from PyQt6.QtWidgets import QTreeWidgetItem, QAbstractItemView, QWidget, QMenu
 
 from EricWidgets.EricApplication import ericApp
 from EricGui.EricOverrideCursor import EricOverrideCursor
@@ -32,6 +30,7 @@
     """
     Class implementing the disassembly viewer operation modes.
     """
+
     SOURCEDISASSEMBLY = 0
     TRACEBACK = 1
 
@@ -41,16 +40,17 @@
     Class implementing a widget to visualize the Python Disassembly for some
     Python sources.
     """
+
     StartLineRole = Qt.ItemDataRole.UserRole
     EndLineRole = Qt.ItemDataRole.UserRole + 1
     CodeInfoRole = Qt.ItemDataRole.UserRole + 2
-    
-    def __init__(self, viewmanager,
-                 mode=PythonDisViewerModes.SOURCEDISASSEMBLY,
-                 parent=None):
+
+    def __init__(
+        self, viewmanager, mode=PythonDisViewerModes.SOURCEDISASSEMBLY, parent=None
+    ):
         """
         Constructor
-        
+
         @param viewmanager reference to the viewmanager object
         @type ViewManager
         @param mode operation mode of the viewer
@@ -60,84 +60,86 @@
         """
         super().__init__(parent)
         self.setupUi(self)
-        
+
         self.setWindowTitle(self.tr("Disassembly"))
-        
+
         self.__vm = viewmanager
         self.__vmConnected = False
-        
+
         self.__mode = mode
-        
+
         self.__editor = None
         self.__source = ""
-        
+
         self.disWidget.setHeaderLabels(
-            [self.tr("Line"), self.tr("Offset"), self.tr("Operation"),
-             self.tr("Parameters"), self.tr("Interpreted Parameters")])
-        self.codeInfoWidget.setHeaderLabels(
-            [self.tr("Key"), self.tr("Value")])
-        
+            [
+                self.tr("Line"),
+                self.tr("Offset"),
+                self.tr("Operation"),
+                self.tr("Parameters"),
+                self.tr("Interpreted Parameters"),
+            ]
+        )
+        self.codeInfoWidget.setHeaderLabels([self.tr("Key"), self.tr("Value")])
+
         self.__disMenu = QMenu(self.disWidget)
         if self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY:
             self.__codeInfoAct = self.__disMenu.addAction(
-                self.tr("Show Code Info"), self.__showCodeInfo)
+                self.tr("Show Code Info"), self.__showCodeInfo
+            )
             self.__disMenu.addSeparator()
-        self.__disMenu.addAction(
-            self.tr('Expand All'), self.__expandAllDis)
-        self.__disMenu.addAction(
-            self.tr('Collapse All'), self.__collapseAllDis)
+        self.__disMenu.addAction(self.tr("Expand All"), self.__expandAllDis)
+        self.__disMenu.addAction(self.tr("Collapse All"), self.__collapseAllDis)
         self.__disMenu.addSeparator()
-        self.__disMenu.addAction(
-            self.tr('Configure...'), self.__configure)
-        
+        self.__disMenu.addAction(self.tr("Configure..."), self.__configure)
+
         self.__codeInfoMenu = QMenu(self.codeInfoWidget)
         if self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY:
-            self.__codeInfoMenu.addAction(
-                self.tr("Hide"), self.codeInfoWidget.hide)
-        self.__codeInfoMenu.addAction(
-            self.tr('Expand All'), self.__expandAllCodeInfo)
-        self.__codeInfoMenu.addAction(
-            self.tr('Collapse All'), self.__collapseAllCodeInfo)
-        self.__codeInfoMenu.addSeparator()
+            self.__codeInfoMenu.addAction(self.tr("Hide"), self.codeInfoWidget.hide)
+        self.__codeInfoMenu.addAction(self.tr("Expand All"), self.__expandAllCodeInfo)
         self.__codeInfoMenu.addAction(
-            self.tr('Configure...'), self.__configure)
-        
-        self.__errorColor = QBrush(
-            Preferences.getPython("DisViewerErrorColor"))
+            self.tr("Collapse All"), self.__collapseAllCodeInfo
+        )
+        self.__codeInfoMenu.addSeparator()
+        self.__codeInfoMenu.addAction(self.tr("Configure..."), self.__configure)
+
+        self.__errorColor = QBrush(Preferences.getPython("DisViewerErrorColor"))
         self.__currentInstructionColor = QBrush(
-            Preferences.getPython("DisViewerCurrentColor"))
-        self.__jumpTargetColor = QBrush(
-            Preferences.getPython("DisViewerLabeledColor"))
-        
+            Preferences.getPython("DisViewerCurrentColor")
+        )
+        self.__jumpTargetColor = QBrush(Preferences.getPython("DisViewerLabeledColor"))
+
         self.__showCodeInfoDetails = Preferences.getPython(
-            "DisViewerExpandCodeInfoDetails")
-        
+            "DisViewerExpandCodeInfoDetails"
+        )
+
         if self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY:
             self.disWidget.itemClicked.connect(self.__disItemClicked)
         self.disWidget.itemCollapsed.connect(self.__resizeDisColumns)
         self.disWidget.itemExpanded.connect(self.__resizeDisColumns)
         self.disWidget.customContextMenuRequested.connect(
-            self.__disContextMenuRequested)
-        
+            self.__disContextMenuRequested
+        )
+
         self.codeInfoWidget.itemCollapsed.connect(self.__resizeCodeInfoColumns)
         self.codeInfoWidget.itemExpanded.connect(self.__resizeCodeInfoColumns)
         self.codeInfoWidget.customContextMenuRequested.connect(
-            self.__codeInfoContextMenuRequested)
-        
+            self.__codeInfoContextMenuRequested
+        )
+
         if self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY:
-            self.__vm.disViewerStateChanged.connect(
-                self.__disViewerStateChanged)
-            
+            self.__vm.disViewerStateChanged.connect(self.__disViewerStateChanged)
+
             self.codeInfoWidget.hide()
             self.hide()
-        
+
         elif self.__mode == PythonDisViewerModes.TRACEBACK:
             self.__styleLabels()
-    
+
     def __disContextMenuRequested(self, coord):
         """
         Private slot to show the context menu of the disassembly widget.
-        
+
         @param coord position of the mouse pointer
         @type QPoint
         """
@@ -145,16 +147,16 @@
             itm = self.disWidget.itemAt(coord)
             self.__codeInfoAct.setEnabled(bool(itm.data(0, self.CodeInfoRole)))
             self.disWidget.setCurrentItem(itm)
-        
+
         if self.disWidget.topLevelItemCount() > 0:
             # don't show context menu on empty list
             coord = self.disWidget.mapToGlobal(coord)
             self.__disMenu.popup(coord)
-    
+
     def __editorChanged(self, editor):
         """
         Private slot to handle a change of the current editor.
-        
+
         @param editor reference to the current editor
         @type Editor
         """
@@ -164,22 +166,22 @@
             self.__editor = editor
             if self.__editor:
                 self.__loadDIS()
-    
+
     def __editorSaved(self, editor):
         """
         Private slot to reload the Disassembly after the connected editor was
         saved.
-        
+
         @param editor reference to the editor that performed a save action
         @type Editor
         """
         if editor and editor is self.__editor:
             self.__loadDIS()
-    
+
     def __editorLineChanged(self, editor, lineno):
         """
         Private slot to handle a mouse button double click in the editor.
-        
+
         @param editor reference to the editor, that emitted the signal
         @type Editor
         @param lineno line number of the editor's cursor (zero based)
@@ -189,76 +191,71 @@
             if editor.isModified():
                 # reload the source
                 QTimer.singleShot(0, self.__loadDIS)
-            
+
             # highlight the corresponding entry
             QTimer.singleShot(0, self.__selectItemForEditorLine)
-    
+
     def __editorLanguageChanged(self, editor):
         """
         Private slot to handle a change of the editor language.
-        
+
         @param editor reference to the editor which changed language
         @type Editor
         """
         if editor is self.__editor:
             QTimer.singleShot(0, self.__loadDIS)
-    
+
     def __lastEditorClosed(self):
         """
         Private slot to handle the last editor closed signal of the view
         manager.
         """
         self.hide()
-    
+
     def show(self):
         """
         Public slot to show the DIS viewer.
         """
         super().show()
-        
+
         if (
-            self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY and
-            not self.__vmConnected
+            self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY
+            and not self.__vmConnected
         ):
             self.__vm.editorChangedEd.connect(self.__editorChanged)
             self.__vm.editorSavedEd.connect(self.__editorSaved)
             self.__vm.editorLineChangedEd.connect(self.__editorLineChanged)
-            self.__vm.editorLanguageChanged.connect(
-                self.__editorLanguageChanged)
+            self.__vm.editorLanguageChanged.connect(self.__editorLanguageChanged)
             self.__vmConnected = True
-        
+
         self.__styleLabels()
-    
+
     def hide(self):
         """
         Public slot to hide the DIS viewer.
         """
         super().hide()
-        
+
         if self.__editor:
             self.__editor.clearAllHighlights()
-        
-        if (
-            self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY and
-            self.__vmConnected
-        ):
+
+        if self.__mode == PythonDisViewerModes.SOURCEDISASSEMBLY and self.__vmConnected:
             self.__vm.editorChangedEd.disconnect(self.__editorChanged)
             self.__vm.editorSavedEd.disconnect(self.__editorSaved)
             self.__vm.editorLineChangedEd.disconnect(self.__editorLineChanged)
-            self.__vm.editorLanguageChanged.disconnect(
-                self.__editorLanguageChanged)
+            self.__vm.editorLanguageChanged.disconnect(self.__editorLanguageChanged)
             self.__vmConnected = False
-    
+
     def shutdown(self):
         """
         Public method to perform shutdown actions.
         """
         self.__editor = None
-    
+
     def __disViewerStateChanged(self, on):
         """
         Private slot to toggle the display of the Disassembly viewer.
-        
+
         @param on flag indicating to show the Disassembly
         @type bool
         """
@@ -272,7 +269,7 @@
             else:
                 self.hide()
                 self.__editor = None
-    
+
     def __expandAllDis(self):
         """
         Private slot to expand all items of the disassembly widget.
@@ -281,7 +278,7 @@
         self.disWidget.expandAll()
         self.disWidget.blockSignals(block)
         self.__resizeDisColumns()
-    
+
     def __collapseAllDis(self):
         """
         Private slot to collapse all items of the disassembly widget.
@@ -290,11 +287,11 @@
         self.disWidget.collapseAll()
         self.disWidget.blockSignals(block)
         self.__resizeDisColumns()
-    
+
     def __createErrorItem(self, error):
         """
         Private method to create a top level error item.
-        
+
         @param error error message
         @type str
         @return generated item
@@ -304,11 +301,11 @@
         itm.setFirstColumnSpanned(True)
         itm.setForeground(0, self.__errorColor)
         return itm
-    
+
     def __createTitleItem(self, title, line, parentItem):
         """
         Private method to create a title item.
-        
+
         @param title titel string for the item
         @type str
         @param line start line of the titled disassembly
@@ -321,16 +318,16 @@
         itm = QTreeWidgetItem(parentItem, [title])
         itm.setFirstColumnSpanned(True)
         itm.setExpanded(True)
-        
+
         itm.setData(0, self.StartLineRole, line)
         itm.setData(0, self.EndLineRole, line)
-        
+
         return itm
-    
+
     def __createInstructionItem(self, instr, parent, lasti=-1):
         """
         Private method to create an item for the given instruction.
-        
+
         @param instr instruction the item should be based on
         @type dis.Instruction
         @param parent reference to the parent item
@@ -356,8 +353,8 @@
             fields.append(repr(instr.arg))
             # Column: Opcode argument details
             if instr.argrepr:
-                fields.append('(' + instr.argrepr + ')')
-        
+                fields.append("(" + instr.argrepr + ")")
+
         itm = QTreeWidgetItem(parent, fields)
         for col in (0, 1, 3):
             itm.setTextAlignment(col, Qt.AlignmentFlag.AlignRight)
@@ -379,9 +376,9 @@
         if foreground:
             for col in range(itm.columnCount()):
                 itm.setForeground(col, foreground)
-        
+
         itm.setExpanded(True)
-        
+
         if instr.starts_line:
             itm.setData(0, self.StartLineRole, instr.starts_line)
             itm.setData(0, self.EndLineRole, instr.starts_line)
@@ -391,26 +388,28 @@
             itm.setData(0, self.StartLineRole, lineno)
             itm.setData(0, self.EndLineRole, lineno)
         return itm
-    
+
     def __updateItemEndLine(self, itm):
         """
         Private method to update an items end line based on its children.
-        
+
         @param itm reference to the item to be updated
         @type QTreeWidgetItem
         """
         endLine = (
-            max(itm.child(index).data(0, self.EndLineRole)
-                for index in range(itm.childCount()))
-            if itm.childCount() else
-            itm.data(0, self.StartLineRole)
+            max(
+                itm.child(index).data(0, self.EndLineRole)
+                for index in range(itm.childCount())
+            )
+            if itm.childCount()
+            else itm.data(0, self.StartLineRole)
         )
         itm.setData(0, self.EndLineRole, endLine)
-    
+
     def __createCodeInfo(self, co):
         """
         Private method to create a dictionary containing the code info data.
-        
+
         @param co reference to the code object to generate the info for
         @type code
         @return dictionary containing the code info data
@@ -436,9 +435,9 @@
         except AttributeError:
             # does not exist prior to 3.8.0
             codeInfoDict["posonlyargcount"] = 0
-        
+
         return codeInfoDict
-    
+
     def __loadDIS(self):
         """
         Private method to generate the Disassembly from the source of the
@@ -447,84 +446,82 @@
         if self.__mode != PythonDisViewerModes.SOURCEDISASSEMBLY:
             # wrong mode, just return
             return
-        
+
         if not self.__editor:
-            self.__createErrorItem(self.tr(
-                "No editor has been opened."
-            ))
+            self.__createErrorItem(self.tr("No editor has been opened."))
             return
-        
+
         self.clear()
         self.__editor.clearAllHighlights()
         self.codeInfoWidget.hide()
-        
+
         source = self.__editor.text()
         if not source.strip():
             # empty editor or white space only
-            self.__createErrorItem(self.tr(
-                "The current editor does not contain any source code."
-            ))
+            self.__createErrorItem(
+                self.tr("The current editor does not contain any source code.")
+            )
             return
-        
+
         if not self.__editor.isPyFile():
-            self.__createErrorItem(self.tr(
-                "The current editor does not contain Python source code."
-            ))
+            self.__createErrorItem(
+                self.tr("The current editor does not contain Python source code.")
+            )
             return
-        
+
         filename = self.__editor.getFileName()
         filename = os.path.basename(filename) if filename else "<dis>"
-        
+
         with EricOverrideCursor():
             try:
                 codeObject = tryCompile(source, filename)
             except Exception as exc:
                 codeObject = None
                 self.__createErrorItem(str(exc))
-            
+
             if codeObject:
                 self.setUpdatesEnabled(False)
                 block = self.disWidget.blockSignals(True)
-                
+
                 self.__disassembleObject(codeObject, self.disWidget, filename)
                 QTimer.singleShot(0, self.__resizeDisColumns)
-                
+
                 self.disWidget.blockSignals(block)
                 self.setUpdatesEnabled(True)
-    
+
     @pyqtSlot(dict)
     def showDisassembly(self, disassembly):
         """
         Public slot to receive a code disassembly from the debug client.
-        
+
         @param disassembly dictionary containing the disassembly information
         @type dict
         """
         if (
-            self.__mode == PythonDisViewerModes.TRACEBACK and
-            disassembly and
-            "instructions" in disassembly and
-            disassembly["instructions"]
+            self.__mode == PythonDisViewerModes.TRACEBACK
+            and disassembly
+            and "instructions" in disassembly
+            and disassembly["instructions"]
         ):
             self.disWidget.clear()
-            
+
             self.setUpdatesEnabled(False)
             block = self.disWidget.blockSignals(True)
-            
+
             titleItem = self.__createTitleItem(
                 self.tr("Disassembly of last traceback"),
                 disassembly["firstlineno"],
-                self.disWidget
+                self.disWidget,
             )
-            
+
             lasti = disassembly["lasti"]
             lastStartItem = None
             for instrDict in disassembly["instructions"]:
                 instr = dis.Instruction(
                     instrDict["opname"],
-                    0,                              # dummy value
+                    0,  # dummy value
                     instrDict["arg"],
-                    "",                             # dummy value
+                    "",  # dummy value
                     instrDict["argrepr"],
                     instrDict["offset"],
                     instrDict["lineno"],
@@ -534,33 +531,33 @@
                     if lastStartItem:
                         self.__updateItemEndLine(lastStartItem)
                     lastStartItem = self.__createInstructionItem(
-                        instr, titleItem, lasti=lasti)
+                        instr, titleItem, lasti=lasti
+                    )
                 else:
-                    self.__createInstructionItem(
-                        instr, lastStartItem, lasti=lasti)
+                    self.__createInstructionItem(instr, lastStartItem, lasti=lasti)
             if lastStartItem:
                 self.__updateItemEndLine(lastStartItem)
-            
+
             QTimer.singleShot(0, self.__resizeDisColumns)
-            
+
             self.disWidget.blockSignals(block)
             self.setUpdatesEnabled(True)
-            
+
             if lasti:
                 lastInstructions = self.disWidget.findItems(
                     "{0:d}".format(lasti),
-                    Qt.MatchFlag.MatchFixedString |
-                    Qt.MatchFlag.MatchRecursive,
-                    1
+                    Qt.MatchFlag.MatchFixedString | Qt.MatchFlag.MatchRecursive,
+                    1,
                 )
                 if lastInstructions:
                     self.disWidget.scrollToItem(
                         lastInstructions[0],
-                        QAbstractItemView.ScrollHint.PositionAtCenter)
-            
+                        QAbstractItemView.ScrollHint.PositionAtCenter,
+                    )
+
             if "codeinfo" in disassembly:
                 self.__showCodeInfoData(disassembly["codeinfo"])
-    
+
     def __resizeDisColumns(self):
         """
         Private method to resize the columns of the disassembly widget to
@@ -568,30 +565,30 @@
         """
         for col in range(self.disWidget.columnCount()):
             self.disWidget.resizeColumnToContents(col)
-    
+
     def resizeEvent(self, evt):
         """
         Protected method to handle resize events.
-        
+
         @param evt resize event
         @type QResizeEvent
         """
         # just adjust the sizes of the columns
         self.__resizeDisColumns()
         self.__resizeCodeInfoColumns()
-    
+
     def __clearSelection(self):
         """
         Private method to clear all selected items.
         """
         for itm in self.disWidget.selectedItems():
             itm.setSelected(False)
-    
+
     def __selectChildren(self, itm, lineno):
         """
         Private method to select children of the given item covering the given
         line number.
-        
+
         @param itm reference to the item
         @type QTreeWidgetItem
         @param lineno line number to base the selection on
@@ -600,16 +597,18 @@
         for index in range(itm.childCount()):
             child = itm.child(index)
             if (
-                child.data(0, self.StartLineRole) <= lineno <=
-                child.data(0, self.EndLineRole)
+                child.data(0, self.StartLineRole)
+                <= lineno
+                <= child.data(0, self.EndLineRole)
             ):
                 child.setSelected(True)
                 self.__selectChildren(child, lineno)
-            
+
             if child.data(0, self.StartLineRole) == lineno:
                 self.disWidget.scrollToItem(
-                    child, QAbstractItemView.ScrollHint.PositionAtCenter)
-    
+                    child, QAbstractItemView.ScrollHint.PositionAtCenter
+                )
+
     def __selectItemForEditorLine(self):
         """
         Private slot to select the items corresponding with the cursor line
@@ -617,45 +616,45 @@
         """
         # step 1: clear all selected items
         self.__clearSelection()
-        
+
         # step 2: retrieve the editor cursor line
         cline, cindex = self.__editor.getCursorPosition()
         # make the line numbers 1-based
         cline += 1
-        
+
         for index in range(self.disWidget.topLevelItemCount()):
             itm = self.disWidget.topLevelItem(index)
             if (
-                itm.data(0, self.StartLineRole) <= cline <=
-                itm.data(0, self.EndLineRole)
+                itm.data(0, self.StartLineRole)
+                <= cline
+                <= itm.data(0, self.EndLineRole)
             ):
                 itm.setSelected(True)
                 self.__selectChildren(itm, cline)
-    
+
     @pyqtSlot(QTreeWidgetItem, int)
     def __disItemClicked(self, itm, column):
         """
         Private slot handling a user click on a Disassembly node item.
-        
+
         @param itm reference to the clicked item
         @type QTreeWidgetItem
         @param column column number of the click
         @type int
         """
         self.__editor.clearAllHighlights()
-        
+
         if itm is not None:
             startLine = itm.data(0, self.StartLineRole)
             endLine = itm.data(0, self.EndLineRole)
-            
-            self.__editor.gotoLine(startLine, firstVisible=True,
-                                   expand=True)
+
+            self.__editor.gotoLine(startLine, firstVisible=True, expand=True)
             self.__editor.setHighlight(startLine - 1, 0, endLine, -1)
-    
+
     def __disassembleObject(self, co, parentItem, parentName="", lasti=-1):
         """
         Private method to disassemble the given code object recursively.
-        
+
         @param co code object to be disassembled
         @type code object
         @param parentItem reference to the parent item
@@ -674,51 +673,50 @@
             else:
                 name = co.co_name
             title = self.tr("Code Object '{0}'").format(name)
-        titleItem = self.__createTitleItem(title, co.co_firstlineno,
-                                           parentItem)
+        titleItem = self.__createTitleItem(title, co.co_firstlineno, parentItem)
         codeInfo = self.__createCodeInfo(co)
         if codeInfo:
             titleItem.setData(0, self.CodeInfoRole, codeInfo)
-        
+
         lastStartItem = None
         for instr in dis.get_instructions(co):
             if instr.starts_line:
                 if lastStartItem:
                     self.__updateItemEndLine(lastStartItem)
                 lastStartItem = self.__createInstructionItem(
-                    instr, titleItem, lasti=lasti)
+                    instr, titleItem, lasti=lasti
+                )
             else:
                 self.__createInstructionItem(instr, lastStartItem, lasti=lasti)
         if lastStartItem:
             self.__updateItemEndLine(lastStartItem)
-        
+
         for x in co.co_consts:
-            if hasattr(x, 'co_code'):
-                self.__disassembleObject(x, titleItem, parentName=name,
-                                         lasti=lasti)
-        
+            if hasattr(x, "co_code"):
+                self.__disassembleObject(x, titleItem, parentName=name, lasti=lasti)
+
         self.__updateItemEndLine(titleItem)
-    
+
     @pyqtSlot()
     def preferencesChanged(self):
         """
         Public slot handling changes of the Disassembly viewer settings.
         """
-        self.__errorColor = QBrush(
-            Preferences.getPython("DisViewerErrorColor"))
+        self.__errorColor = QBrush(Preferences.getPython("DisViewerErrorColor"))
         self.__currentInstructionColor = QBrush(
-            Preferences.getPython("DisViewerCurrentColor"))
-        self.__jumpTargetColor = QBrush(
-            Preferences.getPython("DisViewerLabeledColor"))
-        
+            Preferences.getPython("DisViewerCurrentColor")
+        )
+        self.__jumpTargetColor = QBrush(Preferences.getPython("DisViewerLabeledColor"))
+
         self.__showCodeInfoDetails = Preferences.getPython(
-            "DisViewerExpandCodeInfoDetails")
-        
+            "DisViewerExpandCodeInfoDetails"
+        )
+
         if self.isVisible():
             self.__loadDIS()
-        
+
         self.__styleLabels()
-    
+
     def __styleLabels(self):
         """
         Private method to style the info labels iaw. selected colors.
@@ -732,17 +730,15 @@
         font = self.currentInfoLabel.font()
         font.setItalic(True)
         self.currentInfoLabel.setFont(font)
-        
+
         # labeled instruction
         self.labeledInfoLabel.setStyleSheet(
-            "QLabel {{ color : {0}; }}".format(
-                self.__jumpTargetColor.color().name()
-            )
+            "QLabel {{ color : {0}; }}".format(self.__jumpTargetColor.color().name())
         )
         font = self.labeledInfoLabel.font()
         font.setBold(True)
         self.labeledInfoLabel.setFont(font)
-    
+
     @pyqtSlot()
     def clear(self):
         """
@@ -750,7 +746,7 @@
         """
         self.disWidget.clear()
         self.codeInfoWidget.clear()
-    
+
     def __showCodeInfo(self):
         """
         Private slot handling the context menu action to show code info.
@@ -760,72 +756,78 @@
         if codeInfo:
             self.codeInfoWidget.show()
             self.__showCodeInfoData(codeInfo)
-    
+
     def __showCodeInfoData(self, codeInfo):
         """
         Private method to show the passed code info data.
-        
+
         @param codeInfo dictionary containing the code info data
         @type dict
         """
+
         def createCodeInfoItems(title, infoList):
             """
             Function to create code info items for the given list.
-            
+
             @param title title string for the list
             @type str
             @param infoList list of info strings
             @type list of str
             """
-            parent = QTreeWidgetItem(self.codeInfoWidget,
-                                     [title, str(len(infoList))])
+            parent = QTreeWidgetItem(self.codeInfoWidget, [title, str(len(infoList))])
             parent.setExpanded(self.__showCodeInfoDetails)
-            
+
             for index, value in enumerate(infoList):
                 itm = QTreeWidgetItem(parent, [str(index), str(value)])
                 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight)
-        
+
         self.codeInfoWidget.clear()
-        
+
         if codeInfo:
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Name"), codeInfo["name"]])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Filename"), codeInfo["filename"]])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("First Line"), str(codeInfo["firstlineno"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Argument Count"), str(codeInfo["argcount"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Positional-only Arguments"),
-                str(codeInfo["posonlyargcount"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Keyword-only Arguments"),
-                str(codeInfo["kwonlyargcount"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Number of Locals"), str(codeInfo["nlocals"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Stack Size"), str(codeInfo["stacksize"])])
-            QTreeWidgetItem(self.codeInfoWidget, [
-                self.tr("Flags"), codeInfo["flags"]])
+            QTreeWidgetItem(self.codeInfoWidget, [self.tr("Name"), codeInfo["name"]])
+            QTreeWidgetItem(
+                self.codeInfoWidget, [self.tr("Filename"), codeInfo["filename"]]
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget,
+                [self.tr("First Line"), str(codeInfo["firstlineno"])],
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget,
+                [self.tr("Argument Count"), str(codeInfo["argcount"])],
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget,
+                [
+                    self.tr("Positional-only Arguments"),
+                    str(codeInfo["posonlyargcount"]),
+                ],
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget,
+                [self.tr("Keyword-only Arguments"), str(codeInfo["kwonlyargcount"])],
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget,
+                [self.tr("Number of Locals"), str(codeInfo["nlocals"])],
+            )
+            QTreeWidgetItem(
+                self.codeInfoWidget, [self.tr("Stack Size"), str(codeInfo["stacksize"])]
+            )
+            QTreeWidgetItem(self.codeInfoWidget, [self.tr("Flags"), codeInfo["flags"]])
             if codeInfo["consts"]:
-                createCodeInfoItems(self.tr("Constants"),
-                                    codeInfo["consts"])
+                createCodeInfoItems(self.tr("Constants"), codeInfo["consts"])
             if codeInfo["names"]:
-                createCodeInfoItems(self.tr("Names"),
-                                    codeInfo["names"])
+                createCodeInfoItems(self.tr("Names"), codeInfo["names"])
             if codeInfo["varnames"]:
-                createCodeInfoItems(self.tr("Variable Names"),
-                                    codeInfo["varnames"])
+                createCodeInfoItems(self.tr("Variable Names"), codeInfo["varnames"])
             if codeInfo["freevars"]:
-                createCodeInfoItems(self.tr("Free Variables"),
-                                    codeInfo["freevars"])
+                createCodeInfoItems(self.tr("Free Variables"), codeInfo["freevars"])
             if codeInfo["cellvars"]:
-                createCodeInfoItems(self.tr("Cell Variables"),
-                                    codeInfo["cellvars"])
-            
+                createCodeInfoItems(self.tr("Cell Variables"), codeInfo["cellvars"])
+
             QTimer.singleShot(0, self.__resizeCodeInfoColumns)
-    
+
     def __resizeCodeInfoColumns(self):
         """
         Private method to resize the columns of the code info widget to
@@ -833,7 +835,7 @@
         """
         for col in range(self.codeInfoWidget.columnCount()):
             self.codeInfoWidget.resizeColumnToContents(col)
-    
+
     def __expandAllCodeInfo(self):
         """
         Private slot to expand all items of the code info widget.
@@ -842,7 +844,7 @@
         self.codeInfoWidget.expandAll()
         self.codeInfoWidget.blockSignals(block)
         self.__resizeCodeInfoColumns()
-    
+
     def __collapseAllCodeInfo(self):
         """
         Private slot to collapse all items of the code info widget.
@@ -851,11 +853,11 @@
         self.codeInfoWidget.collapseAll()
         self.codeInfoWidget.blockSignals(block)
         self.__resizeCodeInfoColumns()
-    
+
     def __codeInfoContextMenuRequested(self, coord):
         """
         Private slot to show the context menu of the code info widget.
-        
+
         @param coord position of the mouse pointer
         @type QPoint
         """
@@ -863,20 +865,19 @@
             # don't show context menu on empty list
             coord = self.codeInfoWidget.mapToGlobal(coord)
             self.__codeInfoMenu.popup(coord)
-    
+
     def __configure(self):
         """
         Private method to open the configuration dialog.
         """
-        ericApp().getObject("UserInterface").showPreferences(
-            "pythonPage")
+        ericApp().getObject("UserInterface").showPreferences("pythonPage")
 
 
 def tryCompile(source, name):
     """
     Function to attempt to compile the given source, first as an
     expression and then as a statement if the first approach fails.
-    
+
     @param source source code string to be compiled
     @type str
     @param name name of the file containing the source
@@ -885,16 +886,16 @@
     @rtype code object
     """
     try:
-        c = compile(source, name, 'eval')
+        c = compile(source, name, "eval")
     except SyntaxError:
-        c = compile(source, name, 'exec')
+        c = compile(source, name, "exec")
     return c
 
 
 def linestarts(co, filename="", getall=True):
     """
     Function to get the line starts for the given code object.
-    
+
     @param co reference to the compiled code object or the source code
     @type code object or str
     @param filename name of the source file (optional)
@@ -911,10 +912,10 @@
             co = tryCompile(co, fn)
         except SyntaxError:
             return []
-    
+
     starts = [inst[1] for inst in dis.findlinestarts(co)]
     if getall:
         for x in co.co_consts:
-            if hasattr(x, 'co_code'):
+            if hasattr(x, "co_code"):
                 starts.extend(linestarts(x))
     return sorted(starts)

eric ide

mercurial