From 4928b1e0ab064d669f26f4870423fc3ae4f6205a Mon Sep 17 00:00:00 2001 From: bcolsen Date: Sat, 26 May 2018 00:34:09 -0600 Subject: [PATCH] Added a Cython console --- appveyor.yml | 2 +- spyder/plugins/ipythonconsole.py | 28 +++++++++++++------- spyder/plugins/tests/test_ipythonconsole.py | 29 ++++++++++++++++++++- spyder/utils/ipython/kernelspec.py | 10 ++++++- spyder/widgets/ipythonconsole/client.py | 2 +- 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 4b5c0bcc8bc..ed2bbd57fea 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,7 +13,7 @@ environment: rope pyflakes sphinx pygments pylint pycodestyle psutil nbconvert qtawesome cloudpickle pickleshare pyzmq chardet mock pandas pytest pytest-cov numpydoc scipy pillow qtconsole matplotlib jedi pywin32 - sympy + sympy cython PIP_DEPENDENCIES: "pytest-qt pytest-mock pytest-timeout flaky codecov" matrix: diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index f04ce24f7da..9db33c18a39 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -830,19 +830,25 @@ def get_plugin_actions(self): create_pylab_action = create_action( self, - _("Open a new Pylab console " - "(data plotting)"), + _("New Pylab console (data plotting)"), icon=ima.icon('ipython_console'), triggered=self.create_pylab_client, context=Qt.WidgetWithChildrenShortcut) create_sympy_action = create_action( self, - _("Open a new SymPy console " - "(symbolic math)"), + _("New SymPy console (symbolic math)"), icon=ima.icon('ipython_console'), triggered=self.create_sympy_client, context=Qt.WidgetWithChildrenShortcut) + + create_cython_action = create_action( + self, + _("New Cython console (Python with " + "C-extensions)"), + icon=ima.icon('ipython_console'), + triggered=self.create_cython_client, + context=Qt.WidgetWithChildrenShortcut) restart_action = create_action(self, _("Restart kernel"), icon=ima.icon('restart'), @@ -865,13 +871,15 @@ def get_plugin_actions(self): main_consoles_menu.insert(0, create_client_action) main_consoles_menu.insert(1, create_pylab_action) main_consoles_menu.insert(2, create_sympy_action) + main_consoles_menu.insert(3, create_cython_action) main_consoles_menu += [MENU_SEPARATOR, restart_action, connect_to_kernel_action, MENU_SEPARATOR] # Plugin actions self.menu_actions = [create_client_action, create_pylab_action, - create_sympy_action, MENU_SEPARATOR, + create_sympy_action, create_cython_action, + MENU_SEPARATOR, restart_action, connect_to_kernel_action, MENU_SEPARATOR, rename_tab_action, MENU_SEPARATOR] @@ -1115,13 +1123,15 @@ def create_new_client(self, give_focus=True, filename='', is_cython=False, def create_pylab_client(self): """Force creation of Pylab client""" - console_name = "Pylab" - self.create_new_client(is_pylab=True, given_name=console_name) + self.create_new_client(is_pylab=True, given_name="Pylab") def create_sympy_client(self): """Force creation of SymPy client""" - console_name = "SymPy" - self.create_new_client(is_sympy=True, given_name=console_name) + self.create_new_client(is_sympy=True, given_name="SymPy") + + def create_cython_client(self): + """Force creation of Cython client""" + self.create_new_client(is_cython=True, given_name="Cython") @Slot() def create_client_for_kernel(self): diff --git a/spyder/plugins/tests/test_ipythonconsole.py b/spyder/plugins/tests/test_ipythonconsole.py index 13bd7036bc7..e41ab078f94 100644 --- a/spyder/plugins/tests/test_ipythonconsole.py +++ b/spyder/plugins/tests/test_ipythonconsole.py @@ -97,13 +97,18 @@ def ipyconsole(qtbot, request): sympy_client = request.node.get_marker('sympy_client') is_sympy = True if sympy_client else False + # Start a Cython client if requested + cython_client = request.node.get_marker('cython_client') + is_cython = True if cython_client else False + # Create the console and a new client console = IPythonConsole(parent=None, testing=True, test_dir=test_dir, test_no_stderr=test_no_stderr) console.create_new_client(is_pylab=is_pylab, - is_sympy=is_sympy) + is_sympy=is_sympy, + is_cython=is_cython) # Close callback def close_console(): @@ -184,6 +189,28 @@ def test_sympy_client(ipyconsole, qtbot): assert 'Error' not in control.toPlainText() +@pytest.mark.slow +@flaky(max_runs=3) +@pytest.mark.cython_client +def test_cython_client(ipyconsole, qtbot): + """Test that the automatic backend is working correctly.""" + # Wait until the window is fully up + shell = ipyconsole.get_current_shellwidget() + qtbot.waitUntil(lambda: shell._prompt_html is not None, + timeout=SHELL_TIMEOUT) + + # This is here to generate further errors + with qtbot.waitSignal(shell.executed): + shell.execute("%%cython\n" + "cdef int ctest(int x, int y):\n" + " return x + y") + + # Assert there are no errors in the console + control = ipyconsole.get_focus_widget() + assert 'NOTE' not in control.toPlainText() + assert 'Error' not in control.toPlainText() + + @pytest.mark.slow @flaky(max_runs=3) def test_tab_rename_for_slaves(ipyconsole, qtbot): diff --git a/spyder/utils/ipython/kernelspec.py b/spyder/utils/ipython/kernelspec.py index f8cb5ca8509..1c17355568c 100644 --- a/spyder/utils/ipython/kernelspec.py +++ b/spyder/utils/ipython/kernelspec.py @@ -132,16 +132,24 @@ def env(self): 'SPY_GREEDY_O': CONF.get('ipython_console', 'greedy_completer'), 'SPY_JEDI_O': CONF.get('ipython_console', 'jedi_completer'), 'SPY_SYMPY_O': CONF.get('ipython_console', 'symbolic_math'), - 'SPY_RUN_CYTHON': self.is_cython, +<<<<<<< 11be84b557cfb64d774c7f5199d2a3dd532ab898 'SPY_TESTING': running_under_pytest() or SAFE_MODE +======= +>>>>>>> Added a Cython console } if self.is_pylab is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = True env_vars['SPY_SYMPY_O'] = False + env_vars['SPY_RUN_CYTHON'] = False if self.is_sympy is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = True + env_vars['SPY_RUN_CYTHON'] = False + if self.is_cython is True: + env_vars['SPY_AUTOLOAD_PYLAB_O'] = False + env_vars['SPY_SYMPY_O'] = False + env_vars['SPY_RUN_CYTHON'] = True # Add our PYTHONPATH to env_vars env_vars.update(pypath) diff --git a/spyder/widgets/ipythonconsole/client.py b/spyder/widgets/ipythonconsole/client.py index 91a8f9c0ce7..1c8648427df 100644 --- a/spyder/widgets/ipythonconsole/client.py +++ b/spyder/widgets/ipythonconsole/client.py @@ -297,7 +297,7 @@ def get_name(self): # Adding id to name client_id = self.id_['int_id'] + u'/' + self.id_['str_id'] name = name + u' ' + client_id - elif self.given_name in ["Pylab", "SymPy"]: + elif self.given_name in ["Pylab", "SymPy", "Cython"]: client_id = self.id_['int_id'] + u'/' + self.id_['str_id'] name = self.given_name + u' ' + client_id else: