From efa3df368551671ea05b84d8f464170b16137fc6 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 20 Sep 2017 19:54:03 -0500 Subject: [PATCH 1/9] IPython console: Emit a signal when the prompt is ready --- spyder/widgets/ipythonconsole/shell.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spyder/widgets/ipythonconsole/shell.py b/spyder/widgets/ipythonconsole/shell.py index 18e0c6b82ec..ec220fc196e 100644 --- a/spyder/widgets/ipythonconsole/shell.py +++ b/spyder/widgets/ipythonconsole/shell.py @@ -52,6 +52,7 @@ class ShellWidget(NamepaceBrowserWidget, HelpWidget, DebuggingWidget): sig_got_reply = Signal() sig_is_spykernel = Signal(object) sig_kernel_restarted = Signal(str) + sig_prompt_ready = Signal() # For global working directory sig_change_cwd = Signal(str) @@ -468,6 +469,12 @@ def _syntax_style_changed(self): else: self._highlighter.set_style_sheet(self.style_sheet) + def _prompt_started_hook(self): + """Emit a signal when the prompt is ready.""" + if not self._reading: + self._highlighter.highlighting_on = True + self.sig_prompt_ready.emit() + #---- Qt methods ---------------------------------------------------------- def focusInEvent(self, event): """Reimplement Qt method to send focus change notification""" From 7bbf802f110b89352c0188b10b420e8961de2ee5 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 20 Sep 2017 19:55:01 -0500 Subject: [PATCH 2/9] IPython console: Hide loading animation when prompt is ready --- spyder/widgets/ipythonconsole/client.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/spyder/widgets/ipythonconsole/client.py b/spyder/widgets/ipythonconsole/client.py index 5157b01ca4e..942232410ed 100644 --- a/spyder/widgets/ipythonconsole/client.py +++ b/spyder/widgets/ipythonconsole/client.py @@ -142,12 +142,6 @@ def __init__(self, plugin, id_, # --- Exit function self.exit_callback = lambda: plugin.close_client(client=self) - # --- Signals - # As soon as some content is printed in the console, stop - # our loading animation - document = self.get_control().document() - document.contentsChange.connect(self._hide_loading_page) - # --- Dialog manager self.dialog_manager = DialogManager() @@ -215,11 +209,15 @@ def configure_shellwidget(self, give_focus=True): # To sync with working directory toolbar self.shellwidget.executed.connect(self.shellwidget.get_cwd) + # To apply style if not create_qss_style(self.shellwidget.syntax_style)[1]: self.shellwidget.silent_execute("%colors linux") else: self.shellwidget.silent_execute("%colors lightbg") + # To hide the loading page + self.shellwidget.sig_prompt_ready.connect(self._hide_loading_page) + def enable_stop_button(self): self.stop_button.setEnabled(True) @@ -516,9 +514,7 @@ def _hide_loading_page(self): self.infowidget.hide() self.shellwidget.show() self.infowidget.setHtml(BLANK) - - document = self.get_control().document() - document.contentsChange.disconnect(self._hide_loading_page) + self.shellwidget.sig_prompt_ready.connect(self._hide_loading_page) def _read_stderr(self): """Read the stderr file of the kernel.""" From e0ab1e57c59c37f7e5c813c72ada5337a2d0070c Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 20 Sep 2017 19:57:37 -0500 Subject: [PATCH 3/9] IPython kernel: Add missing comment --- spyder/utils/ipython/start_kernel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spyder/utils/ipython/start_kernel.py b/spyder/utils/ipython/start_kernel.py index 1f6d6ff70af..85cc890909b 100644 --- a/spyder/utils/ipython/start_kernel.py +++ b/spyder/utils/ipython/start_kernel.py @@ -64,6 +64,8 @@ def kernel_config(): # Until we implement Issue 1052 spy_cfg.InteractiveShell.xmode = 'Plain' + # Using Jedi slow completions a lot for objects + # with big repr's spy_cfg.IPCompleter.use_jedi = False # Run lines of code at startup From bc12aa2b5ae5b66bc16f6010d1c894341826b774 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 20 Sep 2017 21:18:43 -0500 Subject: [PATCH 4/9] IPython console: Correctly clean dedicated consoles --- spyder/plugins/ipythonconsole.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index 3b4676617d4..4c60a34b117 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -860,6 +860,7 @@ def run_script(self, filename, wdir, args, debug, post_mortem, norm = lambda text: remove_backslashes(to_text_string(text)) # Select client to execute code on it + is_new_client = False if current_client: client = self.get_current_client() else: @@ -867,6 +868,7 @@ def run_script(self, filename, wdir, args, debug, post_mortem, if client is None: self.create_client_for_file(filename) client = self.get_current_client() + is_new_client = True if client is not None: # Internal kernels, use runfile @@ -888,7 +890,16 @@ def run_script(self, filename, wdir, args, debug, post_mortem, if args: line += " %s" % norm(args) try: - self.execute_code(line, current_client, clear_variables) + if current_client: + self.execute_code(line, current_client, clear_variables) + else: + if is_new_client: + client.shellwidget.silent_execute('%clear') + else: + client.shellwidget.execute('%clear') + client.shellwidget.sig_prompt_ready.connect( + lambda : self.execute_code(line, current_client, + clear_variables)) except AttributeError: pass self.visibility_changed(True) @@ -930,7 +941,7 @@ def execute_code(self, lines, current_client=True, clear_variables=False): if not current_client: # Clear console and reset namespace for # dedicated clients - sw.silent_execute('%clear') + sw.sig_prompt_ready.disconnect() sw.silent_execute( 'get_ipython().kernel.close_all_mpl_figures()') sw.reset_namespace(warning=False, silent=True) From 6dab74486c449ff9bf23791432df88ba2a0f1941 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 20 Sep 2017 21:20:27 -0500 Subject: [PATCH 5/9] IPython console: Increase three times hb_channel.time_to_dead per user request --- spyder/plugins/ipythonconsole.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index 4c60a34b117..f9e5ff9decd 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -1438,7 +1438,7 @@ def create_kernel_manager_and_kernel_client(self, connection_file, # Increase time to detect if a kernel is alive # See Issue 3444 - kernel_client.hb_channel.time_to_dead = 6.0 + kernel_client.hb_channel.time_to_dead = 18.0 return kernel_manager, kernel_client From 3cc0dfea8b6df952b158c6e0df2d746e455d9e8d Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Thu, 21 Sep 2017 08:21:40 -0500 Subject: [PATCH 6/9] IPython console: Remove unneeded import --- spyder/plugins/ipythonconsole.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index f9e5ff9decd..d792d7fdaf3 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -52,7 +52,7 @@ from spyder.utils.ipython.style import create_qss_style from spyder.utils.qthelpers import create_action, MENU_SEPARATOR from spyder.utils import icon_manager as ima -from spyder.utils import encoding, programs, sourcecode +from spyder.utils import programs, sourcecode from spyder.utils.programs import TEMPDIR from spyder.utils.misc import get_error_match, remove_backslashes from spyder.widgets.findreplace import FindReplace From a57fd6f0ef0ca1c58034367c19ffbd48220e6f28 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 11 Oct 2017 18:08:40 -0500 Subject: [PATCH 7/9] Fix style issue --- spyder/plugins/ipythonconsole.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index d792d7fdaf3..c4ee674842f 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -898,8 +898,8 @@ def run_script(self, filename, wdir, args, debug, post_mortem, else: client.shellwidget.execute('%clear') client.shellwidget.sig_prompt_ready.connect( - lambda : self.execute_code(line, current_client, - clear_variables)) + lambda: self.execute_code(line, current_client, + clear_variables)) except AttributeError: pass self.visibility_changed(True) From 744e12744b9221c664d4c33e2e2185c97441d1c5 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 11 Oct 2017 18:45:21 -0500 Subject: [PATCH 8/9] IPython console: Fix error when disconnecting a signal from sig_prompt_ready --- spyder/widgets/ipythonconsole/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyder/widgets/ipythonconsole/client.py b/spyder/widgets/ipythonconsole/client.py index 942232410ed..ffa9d632946 100644 --- a/spyder/widgets/ipythonconsole/client.py +++ b/spyder/widgets/ipythonconsole/client.py @@ -514,7 +514,7 @@ def _hide_loading_page(self): self.infowidget.hide() self.shellwidget.show() self.infowidget.setHtml(BLANK) - self.shellwidget.sig_prompt_ready.connect(self._hide_loading_page) + self.shellwidget.sig_prompt_ready.disconnect(self._hide_loading_page) def _read_stderr(self): """Read the stderr file of the kernel.""" From bfaa791abacb3026857620b3b6fd58899ab854fb Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Wed, 11 Oct 2017 19:05:13 -0500 Subject: [PATCH 9/9] Testing: Add tests for the new functionality added to dedicated consoles --- spyder/app/tests/test_mainwindow.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py index db1c3362f97..5d81f0ac328 100644 --- a/spyder/app/tests/test_mainwindow.py +++ b/spyder/app/tests/test_mainwindow.py @@ -295,6 +295,7 @@ def test_dedicated_consoles(main_window, qtbot): qtbot.keyClick(code_editor, Qt.Key_F5) qtbot.wait(500) shell = main_window.ipyconsole.get_current_shellwidget() + control = shell._control qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) nsb = main_window.variableexplorer.get_focus_widget() @@ -304,6 +305,11 @@ def test_dedicated_consoles(main_window, qtbot): qtbot.wait(500) assert nsb.editor.model.rowCount() == 3 + # --- Assert only runfile text is present and there's no banner text --- + # See PR #5301 + text = control.toPlainText() + assert ('runfile' in text) and not ('Python' in text or 'IPython' in text) + # --- Clean namespace after re-execution --- with qtbot.waitSignal(shell.executed): shell.execute('zz = -1') @@ -311,6 +317,9 @@ def test_dedicated_consoles(main_window, qtbot): qtbot.wait(500) assert not shell.is_defined('zz') + # --- Assert runfile text is present after reruns --- + assert 'runfile' in control.toPlainText() + # ---- Closing test file and resetting config ---- main_window.editor.close_file() CONF.set('run', 'configurations', [])