Repository: spyder-ide/spyder
Pull request: PR: Update Breakpoints plugin to Python 3
<!--- Make sure to read the Contributing Guidelines:                   --->
<!--- https://github.com/spyder-ide/spyder/blob/master/CONTRIBUTING.md --->
<!--- and follow PEP 8, PEP 257 and Spyder's code style:               --->
<!--- https://github.com/spyder-ide/spyder/wiki/Dev:-Coding-Style      --->

## Description of Changes


* [ ] Wrote at least one-line docstrings (for any new functions)
* [ ] Added unit test(s) covering the changes (if testable)
<!--- Remember that an image/animation is worth a thousand words! --->
* [ ] Included a screenshot or animation (if affecting the UI, see [Licecap](https://www.cockos.com/licecap/))


<!--- Explain what you've done and why --->
Migrate the code under the breakpoints plugin from python 2 to python 3



### Issue(s) Resolved

<!--- List the issue(s) below, in the form "Fixes #1234"; one per line --->

Fixes #11616 


### Affirmation

By submitting this Pull Request or typing my (user)name below,
I affirm the [Developer Certificate of Origin](https://developercertificate.org)
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.

<!--- TYPE YOUR USER/NAME AFTER THE FOLLOWING: --->
I certify the above statement is true and correct: Steff456

<!--- Thanks for your help making Spyder better for everyone! --->


Problem statement:
Move breakpoints plugin to python3 only
Take into account the following:

- [ ] Update `super()` use
- [ ] Remove the `py3compat` module
- [ ] Update any code (and remove if necessary) that uses `if PY2` etc...
- [ ] Check division operator
- [ ] Remove future imports
- [ ] Check tests
- [ ] Check for Py2 of Py3 codes

Hints from issue discussion:
https://github.com/spyder-ide/spyder/blob/master/spyder/plugins/breakpoints/widgets/breakpointsgui.py#L53

`QAbstractTableModel.__init__(self, parent)` ->

`super().__init__(parent)`

Commit message: remove pyside code and fix style issues

Patch to review:
diff --git a/spyder/plugins/breakpoints/plugin.py b/spyder/plugins/breakpoints/plugin.py
index 57fa80d2a1c..e9a42230156 100644
--- a/spyder/plugins/breakpoints/plugin.py
+++ b/spyder/plugins/breakpoints/plugin.py
@@ -37,7 +37,7 @@ class Breakpoints(SpyderPluginWidget):
 
     def __init__(self, parent=None):
         """Initialization."""
-        SpyderPluginWidget.__init__(self, parent)
+        super().__init__(parent)
 
         self.breakpoints = BreakpointWidget(self,
                                             options_button=self.options_button)
@@ -51,7 +51,7 @@ def __init__(self, parent=None):
         path = osp.join(self.PLUGIN_PATH, self.IMG_PATH)
         self.icon = ima.icon('breakpoints', icon_path=path)
 
-    #------ SpyderPluginWidget API --------------------------------------------
+    # ----- SpyderPluginWidget API --------------------------------------------
     def get_plugin_title(self):
         """Return widget title"""
         return _("Breakpoints")
@@ -74,7 +74,7 @@ def on_first_registration(self):
     def register_plugin(self):
         """Register plugin in Spyder's main window"""
         self.breakpoints.edit_goto.connect(self.main.editor.load)
-        #self.redirect_stdio.connect(self.main.redirect_internalshell_stdio)
+        # self.redirect_stdio.connect(self.main.redirect_internalshell_stdio)
         self.breakpoints.clear_all_breakpoints.connect(
                                         self.main.editor.clear_all_breakpoints)
         self.breakpoints.clear_breakpoint.connect(
diff --git a/spyder/plugins/breakpoints/widgets/breakpointsgui.py b/spyder/plugins/breakpoints/widgets/breakpointsgui.py
index 5837fba5803..8e0b227f669 100644
--- a/spyder/plugins/breakpoints/widgets/breakpointsgui.py
+++ b/spyder/plugins/breakpoints/widgets/breakpointsgui.py
@@ -39,8 +39,8 @@
 
 COLUMN_COUNT = 4
 EXTRA_COLUMNS = 1
-COL_FILE, COL_LINE, COL_CONDITION, COL_BLANK, COL_FULL = range(COLUMN_COUNT +
-                                                               EXTRA_COLUMNS)
+COL_FILE, COL_LINE, COL_CONDITION, COL_BLANK, COL_FULL = list(
+    range(COLUMN_COUNT + EXTRA_COLUMNS))
 COLUMN_HEADERS = (_("File"), _("Line"), _("Condition"), (""))
 
 
@@ -50,7 +50,7 @@ class BreakpointTableModel(QAbstractTableModel):
     """
 
     def __init__(self, parent, data):
-        QAbstractTableModel.__init__(self, parent)
+        super().__init__(parent)
         if data is None:
             data = {}
         self._data = None
@@ -63,7 +63,7 @@ def set_data(self, data):
         self.breakpoints = []
         files = []
         # Generate list of filenames with active breakpoints
-        for key in data.keys():
+        for key in data:
             if data[key] and key not in files:
                 files.append(key)
         # Insert items
@@ -137,7 +137,7 @@ def reset(self):
 
 class BreakpointDelegate(QItemDelegate):
     def __init__(self, parent=None):
-        QItemDelegate.__init__(self, parent)
+        super().__init__(parent)
 
 
 class BreakpointTableView(QTableView):
@@ -147,7 +147,7 @@ class BreakpointTableView(QTableView):
     set_or_edit_conditional_breakpoint = Signal()
 
     def __init__(self, parent, data):
-        QTableView.__init__(self, parent)
+        super().__init__(parent)
         self.model = BreakpointTableModel(self, data)
         self.setModel(self.model)
         self.delegate = BreakpointDelegate(self)
@@ -184,35 +184,29 @@ def contextMenuEvent(self, event):
         index_clicked = self.indexAt(event.pos())
         actions = []
         self.popup_menu = QMenu(self)
-        clear_all_breakpoints_action = create_action(self,
-            _("Clear breakpoints in all files"),
+        clear_all_breakpoints_action = create_action(
+            self, _("Clear breakpoints in all files"),
             triggered=lambda: self.clear_all_breakpoints.emit())
         actions.append(clear_all_breakpoints_action)
         if self.model.breakpoints:
             c_row = index_clicked.row()
             filename = self.model.breakpoints[c_row][COL_FULL]
             lineno = int(self.model.breakpoints[c_row][COL_LINE])
-            # QAction.triggered works differently for PySide and PyQt
-            if not API == 'pyside':
-                clear_slot = lambda _checked, filename=filename, lineno=lineno: \
-                    self.clear_breakpoint.emit(filename, lineno)
-                edit_slot = lambda _checked, filename=filename, lineno=lineno: \
-                    (self.edit_goto.emit(filename, lineno, ''),
-                     self.set_or_edit_conditional_breakpoint.emit())
-            else:
-                clear_slot = lambda filename=filename, lineno=lineno: \
-                    self.clear_breakpoint.emit(filename, lineno)
-                edit_slot = lambda filename=filename, lineno=lineno: \
-                    (self.edit_goto.emit(filename, lineno, ''),
-                     self.set_or_edit_conditional_breakpoint.emit())
-
-            clear_breakpoint_action = create_action(self,
-                    _("Clear this breakpoint"),
+
+            def clear_slot(filename=filename, lineno=lineno):
+                return self.clear_breakpoint.emit(filename, lineno)
+
+            def edit_slot(filename=filename, lineno=lineno):
+                self.edit_goto.emit(filename, lineno, '')
+                self.set_or_edit_conditional_breakpoint.emit()
+
+            clear_breakpoint_action = create_action(
+                    self, _("Clear this breakpoint"),
                     triggered=clear_slot)
-            actions.insert(0,clear_breakpoint_action)
+            actions.insert(0, clear_breakpoint_action)
 
-            edit_breakpoint_action = create_action(self,
-                    _("Edit this breakpoint"),
+            edit_breakpoint_action = create_action(
+                    self, _("Edit this breakpoint"),
                     triggered=edit_slot)
             actions.append(edit_breakpoint_action)
         add_actions(self.popup_menu, actions)
@@ -231,11 +225,11 @@ class BreakpointWidget(QWidget):
     edit_goto = Signal(str, int, str)
 
     def __init__(self, parent, options_button=None):
-        QWidget.__init__(self, parent)
+        super().__init__(parent)
 
         self.setWindowTitle("Breakpoints")
         self.dictwidget = BreakpointTableView(self,
-                               self._load_all_breakpoints())
+                                              self._load_all_breakpoints())
         if options_button:
             btn_layout = QHBoxLayout()
             btn_layout.setAlignment(Qt.AlignLeft)
@@ -272,9 +266,9 @@ def set_data(self):
         self.dictwidget.sortByColumn(COL_FILE, Qt.DescendingOrder)
 
 
-#==============================================================================
+# =============================================================================
 # Tests
-#==============================================================================
+# =============================================================================
 def test():
     """Run breakpoint widget test"""
     from spyder.utils.qthelpers import qapplication


Code review comments:
diff_hunk: @@ -74,7 +74,7 @@ def on_first_registration(self):
     def register_plugin(self):
         """Register plugin in Spyder's main window"""
         self.breakpoints.edit_goto.connect(self.main.editor.load)
-        #self.redirect_stdio.connect(self.main.redirect_internalshell_stdio)
+        # self.redirect_stdio.connect(self.main.redirect_internalshell_stdio)
path: spyder/plugins/breakpoints/plugin.py
text: @user1:
Let's remove this comment because it doesn't seem necessary anymore.