Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Move breakpoints logic from editor plugin to debugger plugin #19208

Merged
merged 28 commits into from
Sep 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spyder/api/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ def editor(self):

def __init__(self, editor):
""":param editor: CodeEditor instance to control."""
super().__init__()
self._editor = weakref.ref(editor)
58 changes: 29 additions & 29 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,15 +1016,15 @@ def test_move_to_first_breakpoint(main_window, qtbot, debugcell):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# Load test file
test_file = osp.join(LOCATION, 'script.py')
main_window.editor.load(test_file)
code_editor = main_window.editor.get_focus_widget()

# Set breakpoint
code_editor.debugger.toogle_breakpoint(line_number=10)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=10)
qtbot.wait(500)
cursor = code_editor.textCursor()
cursor.setPosition(0)
Expand Down Expand Up @@ -1071,7 +1071,7 @@ def test_move_to_first_breakpoint(main_window, qtbot, debugcell):
shell.pdb_execute("!exit")

# Set breakpoint on first line with code
code_editor.debugger.toogle_breakpoint(line_number=2)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=2)

# Click the debug button
with qtbot.waitSignal(shell.executed):
Expand All @@ -1084,7 +1084,7 @@ def test_move_to_first_breakpoint(main_window, qtbot, debugcell):
assert shell.is_waiting_pdb_input()

# Remove breakpoint and close test file
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()
main_window.editor.close_file()


Expand Down Expand Up @@ -1579,7 +1579,7 @@ def test_set_new_breakpoints(main_window, qtbot):
lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# Load test file
test_file = osp.join(LOCATION, 'script.py')
Expand All @@ -1593,7 +1593,7 @@ def test_set_new_breakpoints(main_window, qtbot):

# Set a breakpoint
code_editor = main_window.editor.get_focus_widget()
code_editor.debugger.toogle_breakpoint(line_number=6)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=6)

# Verify that the breakpoint was set
with qtbot.waitSignal(shell.executed):
Expand All @@ -1602,7 +1602,7 @@ def test_set_new_breakpoints(main_window, qtbot):
test_file) in control.toPlainText()

# Remove breakpoint and close test file
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()
main_window.editor.close_file()


Expand Down Expand Up @@ -2152,7 +2152,7 @@ def test_c_and_n_pdb_commands(main_window, qtbot):
lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# Load test file
test_file = osp.join(LOCATION, 'script.py')
Expand All @@ -2166,7 +2166,7 @@ def test_c_and_n_pdb_commands(main_window, qtbot):

# Set a breakpoint
code_editor = main_window.editor.get_focus_widget()
code_editor.debugger.toogle_breakpoint(line_number=6)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=6)
qtbot.wait(500)

# Verify that c works
Expand Down Expand Up @@ -2212,7 +2212,7 @@ def test_c_and_n_pdb_commands(main_window, qtbot):
assert 'In [2]:' in control.toPlainText()

# Remove breakpoint and close test file
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()
main_window.editor.close_file()


Expand All @@ -2228,7 +2228,7 @@ def test_stop_dbg(main_window, qtbot):
lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# Load test file
test_file = osp.join(LOCATION, 'script.py')
Expand All @@ -2252,7 +2252,7 @@ def test_stop_dbg(main_window, qtbot):
assert shell._control.toPlainText().count('IPdb') == 2

# Remove breakpoint and close test file
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()
main_window.editor.close_file()


Expand Down Expand Up @@ -3020,7 +3020,7 @@ def test_break_while_running(main_window, qtbot, tmpdir):
code_editor = main_window.editor.get_focus_widget()

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# Click the debug button
with qtbot.waitSignal(shell.executed):
Expand All @@ -3034,15 +3034,15 @@ def test_break_while_running(main_window, qtbot, tmpdir):

with qtbot.waitSignal(shell.executed):
# Set a breakpoint
code_editor.debugger.toogle_breakpoint(line_number=3)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=3)
# We should drop into the debugger

with qtbot.waitSignal(shell.executed):
qtbot.keyClicks(shell._control, '!q')
qtbot.keyClick(shell._control, Qt.Key_Enter)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()


# --- Preferences
Expand Down Expand Up @@ -3426,15 +3426,15 @@ def test_debug_unsaved_file(main_window, qtbot):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
code_editor = main_window.editor.get_focus_widget()
code_editor.set_text('print(0)\nprint(1)\nprint(2)')

# Set breakpoint
code_editor.debugger.toogle_breakpoint(line_number=2)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=2)
qtbot.wait(500)

# Start debugging
Expand Down Expand Up @@ -3724,7 +3724,7 @@ def test_runcell_pdb(main_window, qtbot):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
Expand Down Expand Up @@ -4098,13 +4098,13 @@ def test_running_namespace(main_window, qtbot, tmpdir):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
code_editor = main_window.editor.get_focus_widget()
code_editor.set_text(code)
code_editor.debugger.toogle_breakpoint(line_number=2)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=2)

# Write b in the namespace
with qtbot.waitSignal(shell.executed):
Expand Down Expand Up @@ -4161,7 +4161,7 @@ def test_running_namespace_refresh(main_window, qtbot, tmpdir):
timeout=SHELL_TIMEOUT)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

shell.execute(
"runfile(" + repr(str(file2)) + ")"
Expand Down Expand Up @@ -4228,7 +4228,7 @@ def test_debug_namespace(main_window, qtbot, tmpdir):
timeout=SHELL_TIMEOUT)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

with qtbot.waitSignal(shell.executed):
shell.execute(
Expand Down Expand Up @@ -4451,13 +4451,13 @@ def hello():
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
code_editor = main_window.editor.get_focus_widget()
code_editor.set_text(code)
code_editor.debugger.toogle_breakpoint(line_number=4)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=4)

nsb = main_window.variableexplorer.current_widget()

Expand Down Expand Up @@ -4751,13 +4751,13 @@ def test_prevent_closing(main_window, qtbot):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
code_editor = main_window.editor.get_focus_widget()
code_editor.set_text(code)
code_editor.debugger.toogle_breakpoint(line_number=1)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=1)

# Start debugging
with qtbot.waitSignal(shell.executed):
Expand Down Expand Up @@ -4790,7 +4790,7 @@ def test_continue_first_line(main_window, qtbot):
debug_button = main_window.debug_toolbar.widgetForAction(debug_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
Expand Down Expand Up @@ -5335,15 +5335,15 @@ def test_debug_unsaved_function(main_window, qtbot):
run_button = main_window.run_toolbar.widgetForAction(run_action)

# Clear all breakpoints
main_window.editor.clear_all_breakpoints()
main_window.debugger.clear_all_breakpoints()

# create new file
main_window.editor.new()
code_editor = main_window.editor.get_focus_widget()
code_editor.set_text('def foo():\n print(1)')

# Set breakpoint
code_editor.debugger.toogle_breakpoint(line_number=2)
code_editor.breakpoints_manager.toogle_breakpoint(line_number=2)

# run file
with qtbot.waitSignal(shell.executed):
Expand Down
9 changes: 5 additions & 4 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@
'pdb_ignore_lib': False,
'pdb_execute_events': True,
'pdb_use_exclamation_mark': True,
'pdb_stop_first_line': True
'pdb_stop_first_line': True,
'breakpoints_panel': True,
}),
('plots',
{
Expand Down Expand Up @@ -453,8 +454,6 @@
'editor/select all': "Ctrl+A",
# -- In widgets/editor.py
'editor/inspect current object': 'Ctrl+I',
'editor/breakpoint': 'F12',
'editor/conditional breakpoint': 'Shift+F12',
'editor/run selection': "F9",
'editor/run to line': 'Shift+F9',
'editor/run from line': CTRL + '+F9',
Expand Down Expand Up @@ -529,6 +528,8 @@
'debugger/step': "Ctrl+F11",
'debugger/return': "Ctrl+Shift+F11",
'debugger/stop': "Ctrl+Shift+F12",
'debugger/toggle breakpoint': 'F12',
'debugger/toggle conditional breakpoint': 'Shift+F12',
impact27 marked this conversation as resolved.
Show resolved Hide resolved
# ---- In widgets/plots/figurebrowser.py ----
'plots/copy': 'Ctrl+C',
'plots/previous figure': 'Ctrl+PgUp',
Expand Down Expand Up @@ -648,4 +649,4 @@
# or if you want to *rename* options, then you need to do a MAJOR update in
# version, e.g. from 3.0.0 to 4.0.0
# 3. You don't need to touch this value if you're just adding a new option
CONF_VERSION = '72.0.0'
CONF_VERSION = '73.0.0'
57 changes: 34 additions & 23 deletions spyder/plugins/breakpoints/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Breakpoints(SpyderDockablePlugin):
Breakpoint list Plugin.
"""
NAME = 'breakpoints'
REQUIRES = [Plugins.Editor]
REQUIRES = [Plugins.Editor, Plugins.Debugger]
impact27 marked this conversation as resolved.
Show resolved Hide resolved
OPTIONAL = [Plugins.MainMenu]
TABIFY = [Plugins.Help]
WIDGET_CLASS = BreakpointWidget
Expand Down Expand Up @@ -123,41 +123,52 @@ def on_editor_available(self):
editor = self.get_plugin(Plugins.Editor)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)

# TODO: change name of this signal on editor
editor.breakpoints_saved.connect(self.set_data)
widget.sig_clear_all_breakpoints_requested.connect(
editor.clear_all_breakpoints)
widget.sig_clear_breakpoint_requested.connect(editor.clear_breakpoint)
widget.sig_edit_goto_requested.connect(editor.load)
widget.sig_conditional_breakpoint_requested.connect(
editor.set_or_edit_conditional_breakpoint)

# TODO: Fix location once the sections are defined
editor.pythonfile_dependent_actions += [list_action]

@on_plugin_available(plugin=Plugins.MainMenu)
def on_main_menu_available(self):
mainmenu = self.get_plugin(Plugins.MainMenu)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)
mainmenu.add_item_to_application_menu(
list_action, menu_id=ApplicationMenus.Debug)

@on_plugin_teardown(plugin=Plugins.Editor)
def on_editor_teardown(self):
widget = self.get_widget()
editor = self.get_plugin(Plugins.Editor)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)

editor.breakpoints_saved.disconnect(self.set_data)
widget.sig_edit_goto_requested.disconnect(editor.load)
editor.pythonfile_dependent_actions.remove(list_action)

@on_plugin_available(plugin=Plugins.Debugger)
def on_debugger_available(self):
debugger = self.get_plugin(Plugins.Debugger)
widget = self.get_widget()
debugger.get_widget().sig_breakpoints_saved.connect(self.set_data)

widget.sig_clear_all_breakpoints_requested.connect(
debugger.clear_all_breakpoints)
widget.sig_clear_breakpoint_requested.connect(
debugger.clear_breakpoint)
widget.sig_conditional_breakpoint_requested.connect(
debugger._set_or_edit_conditional_breakpoint)

@on_plugin_teardown(plugin=Plugins.Debugger)
def on_debugger_teardown(self):
debugger = self.get_plugin(Plugins.Debugger)
widget = self.get_widget()
debugger.get_widget().sig_breakpoints_saved.disconnect(self.set_data)

widget.sig_clear_all_breakpoints_requested.disconnect(
editor.clear_all_breakpoints)
debugger.clear_all_breakpoints)
widget.sig_clear_breakpoint_requested.disconnect(
editor.clear_breakpoint)
widget.sig_edit_goto_requested.disconnect(editor.load)
debugger.clear_breakpoint)
widget.sig_conditional_breakpoint_requested.disconnect(
editor.set_or_edit_conditional_breakpoint)
debugger._set_or_edit_conditional_breakpoint)

editor.pythonfile_dependent_actions.remove(list_action)
@on_plugin_available(plugin=Plugins.MainMenu)
def on_main_menu_available(self):
mainmenu = self.get_plugin(Plugins.MainMenu)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)
mainmenu.add_item_to_application_menu(
list_action, menu_id=ApplicationMenus.Debug)

@on_plugin_teardown(plugin=Plugins.MainMenu)
def on_main_menu_teardown(self):
Expand All @@ -172,9 +183,9 @@ def _load_data(self):
Load breakpoint data from configuration file.
"""
breakpoints_dict = self.get_conf(
'breakpoints',
"breakpoints",
default={},
section='run',
section='debugger',
)
for filename in list(breakpoints_dict.keys()):
if not osp.isfile(filename):
Expand Down
Loading