From 6e8569968bdb3235da91bf0efb9847a724cd3aed Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Thu, 3 Oct 2024 23:03:19 -0500 Subject: [PATCH] Testing: Check that pdb magics start a recursive debugger --- .../plugins/ipythonconsole/tests/conftest.py | 38 +++++++++++++++++-- .../tests/test_ipythonconsole.py | 36 ++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/spyder/plugins/ipythonconsole/tests/conftest.py b/spyder/plugins/ipythonconsole/tests/conftest.py index dcae4b351f4..65134d3d8fa 100644 --- a/spyder/plugins/ipythonconsole/tests/conftest.py +++ b/spyder/plugins/ipythonconsole/tests/conftest.py @@ -8,6 +8,7 @@ # Standard library imports import os import os.path as osp +from pathlib import Path import sys import threading import traceback @@ -203,9 +204,39 @@ def get_plugin(name): debugger.get_plugin = get_plugin debugger.on_ipython_console_available() + + # Plugin setup console.on_initialize() console._register() console.get_widget().matplotlib_status.register_ipythonconsole(console) + + # Register handlers to run cells. + def get_file_code(fname, save_all=True): + """ + Get code from a file. + + save_all is necessary to keep consistency with the handler registered + in the editor. + """ + path = Path(fname) + return path.read_text() + + def get_cell(cell_id, fname): + """ + Get cell code from a file. + + For now this only works with unnamed cells and cell separators of the + form `# %%`. + """ + path = Path(fname) + contents = path.read_text() + cells = contents.split("# %%") + return cells[int(cell_id)] + + console.register_spyder_kernel_call_handler('get_file_code', get_file_code) + console.register_spyder_kernel_call_handler('run_cell', get_cell) + + # Start client and show window console.create_new_client( special=special, given_name=given_name, @@ -213,9 +244,6 @@ def get_plugin(name): ) window.setCentralWidget(console.get_widget()) - # Set exclamation mark to True - configuration.set('debugger', 'pdb_use_exclamation_mark', True) - if os.name == 'nt': qtbot.addWidget(window) @@ -223,6 +251,10 @@ def get_plugin(name): window.resize(640, 480) window.show() + # Set exclamation mark to True + configuration.set('debugger', 'pdb_use_exclamation_mark', True) + + # Create new client for Matplotlb backend tests if auto_backend or tk_backend: qtbot.wait(SHELL_TIMEOUT) console.create_new_client() diff --git a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py index 931d196c2f1..3dd3a6de3fb 100644 --- a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py +++ b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py @@ -1656,6 +1656,42 @@ def test_recursive_pdb(ipyconsole, qtbot): assert control.toPlainText().split()[-2:] == ["In", "[3]:"] +def test_pdb_magics_are_recursive(ipyconsole, qtbot, tmp_path): + """ + Check that calls to Pdb magics start a recursive debugger when called in + a debugging session. + """ + shell = ipyconsole.get_current_shellwidget() + control = ipyconsole.get_widget().get_focus_widget() + + # Code to run + code = "a = 10\n\n# %%\n\nb = 20" + + # Write code to file on disk + file = tmp_path / 'test_pdb_magics.py' + file.write_text(code) + + # Run file + with qtbot.waitSignal(shell.executed): + shell.execute(f"%debugfile {str(file)}") + + # Run %debugfile in debugger + with qtbot.waitSignal(shell.executed): + shell.pdb_execute(f"%debugfile {str(file)}") + + # Check that there are no errors and we started a recursive debugger + assert "error" not in control.toPlainText().lower() + assert "(IPdb [1]):" in control.toPlainText() + + # Run %debugcell in debugger + with qtbot.waitSignal(shell.executed): + shell.pdb_execute(f"%debugcell -i 0 {str(file)}") + + # Check that there are no errors and we started a recursive debugger + assert "error" not in control.toPlainText().lower() + assert "((IPdb [1])):" in control.toPlainText() + + @flaky(max_runs=3) @pytest.mark.skipif(os.name == 'nt', reason="Doesn't work on windows") def test_stop_pdb(ipyconsole, qtbot):