Skip to content

Commit

Permalink
Merge pull request #20233 from ccordoba12/issue-20023
Browse files Browse the repository at this point in the history
PR: Fix showing Spyder-kernels message on kernel restarts (IPython console)
  • Loading branch information
ccordoba12 committed Dec 21, 2022
2 parents f586c20 + 408691d commit eac428f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 50 deletions.
4 changes: 2 additions & 2 deletions .github/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ python -bb -X dev -W error -m build
python -bb -X dev -W error -m pip install --no-deps dist/spyder*.whl

# Create environment for Jedi environments tests
mamba create -n jedi-test-env -q -y python=3.6 flask spyder-kernels
mamba create -n jedi-test-env -q -y python=3.9 flask spyder-kernels
mamba list -n jedi-test-env

# Create environment to test conda activation before launching a spyder kernel
mamba create -n spytest-ž -q -y python=3.6 spyder-kernels
mamba create -n spytest-ž -q -y python=3.9 spyder-kernels
mamba list -n spytest-ž

# Install pyenv in Posix systems
Expand Down
39 changes: 23 additions & 16 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@
running_in_ci, running_in_ci_with_conda)
from spyder.config.gui import get_color_scheme
from spyder.config.manager import CONF
from spyder.config.utils import is_anaconda
from spyder.py3compat import PY2, to_text_string
from spyder.plugins.help.tests.test_plugin import check_text
from spyder.plugins.help.utils.sphinxify import CSS_PATH
from spyder.plugins.ipythonconsole.plugin import IPythonConsole
from spyder.plugins.ipythonconsole.utils.style import create_style_class
from spyder.plugins.ipythonconsole.widgets import ClientWidget
from spyder.utils.programs import get_temp_dir
from spyder.utils.conda import is_conda_env
from spyder.utils.conda import get_conda_root_prefix


# =============================================================================
Expand All @@ -78,8 +79,11 @@ def get_console_background_color(style_sheet):
return background_color


def get_conda_test_env(test_env_name=u'spytest-ž'):
"""Return the full prefix path of the given `test_env_name`."""
def get_conda_test_env(test_env_name='spytest-ž'):
"""
Return the full prefix path of the given `test_env_name` and its
executable.
"""
if 'envs' in sys.prefix:
root_prefix = os.path.dirname(os.path.dirname(sys.prefix))
else:
Expand All @@ -92,7 +96,7 @@ def get_conda_test_env(test_env_name=u'spytest-ž'):
else:
test_env_executable = os.path.join(test_env_prefix, 'bin', 'python')

return test_env_executable
return (test_env_prefix, test_env_executable)


# =============================================================================
Expand Down Expand Up @@ -196,7 +200,7 @@ def __getattr__(self, attr):
if test_environment_interpreter:
configuration.set('main_interpreter', 'default', False)
configuration.set(
'main_interpreter', 'executable', get_conda_test_env())
'main_interpreter', 'executable', get_conda_test_env()[1])
else:
configuration.set('main_interpreter', 'default', True)
configuration.set('main_interpreter', 'executable', '')
Expand Down Expand Up @@ -1657,6 +1661,8 @@ def test_calltip(ipyconsole, qtbot):
@flaky(max_runs=3)
@pytest.mark.order(1)
@pytest.mark.test_environment_interpreter
@pytest.mark.skipif(not is_anaconda(), reason='Only works with Anaconda')
@pytest.mark.skipif(not running_in_ci(), reason='Only works on CIs')
def test_conda_env_activation(ipyconsole, qtbot):
"""
Test that the conda environment associated with an external interpreter
Expand All @@ -1668,12 +1674,12 @@ def test_conda_env_activation(ipyconsole, qtbot):
# Get conda activation environment variable
with qtbot.waitSignal(shell.executed):
shell.execute(
"import os; conda_prefix = os.environ.get('CONDA_PREFIX')")
"import os; conda_prefix = os.environ.get('CONDA_PREFIX')"
)

expected_output = get_conda_test_env().replace('\\', '/')
if is_conda_env(expected_output):
output = shell.get_value('conda_prefix').replace('\\', '/')
assert expected_output == output
expected_output = get_conda_test_env()[0].replace('\\', '/')
output = shell.get_value('conda_prefix').replace('\\', '/')
assert expected_output == output


@flaky(max_runs=3)
Expand Down Expand Up @@ -2438,8 +2444,7 @@ def test_run_script(ipyconsole, qtbot, tmp_path):


@pytest.mark.skipif(
not sys.platform.startswith('linux'),
reason="Only runs on Linux")
not is_anaconda(), reason="Only works with Anaconda")
def test_show_spyder_kernels_error_on_restart(ipyconsole, qtbot):
"""Test that we show Spyder-kernels error message on restarts."""
# Wait until the window is fully up
Expand All @@ -2449,11 +2454,13 @@ def test_show_spyder_kernels_error_on_restart(ipyconsole, qtbot):

# Point to an interpreter without Spyder-kernels
ipyconsole.set_conf('default', False, section='main_interpreter')
ipyconsole.set_conf('executable', '/usr/bin/python3',
section='main_interpreter')
if os.name == 'nt':
pyexec = osp.join(get_conda_root_prefix(), 'python.exe')
else:
pyexec = osp.join(get_conda_root_prefix(), 'bin', 'python')
ipyconsole.set_conf('executable', pyexec, section='main_interpreter')

# Restart kernel
os.environ['SPY_TEST_SHOW_RESTART_MESSAGE'] = 'true'
ipyconsole.restart_kernel()

# Assert we show a kernel error
Expand All @@ -2467,7 +2474,7 @@ def test_show_spyder_kernels_error_on_restart(ipyconsole, qtbot):
timeout=6000
)

# To check kernel error visually
# To check the kernel error visually
qtbot.wait(500)

# Check kernel related actions are disabled
Expand Down
54 changes: 24 additions & 30 deletions spyder/plugins/ipythonconsole/widgets/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,38 +833,32 @@ def has_spyder_kernels(self):
interpreter=pyexec,
version=SPYDER_KERNELS_VERSION)

if (
not has_spyder_kernels
# This is necessary to show this message for some tests and not
# do it for others.
and os.environ.get('SPY_TEST_SHOW_RESTART_MESSAGE')
):
self.show_kernel_error(
_("The Python environment or installation whose "
"interpreter is located at"
"<pre>"
" <tt>{0}</tt>"
"</pre>"
"doesn't have the <tt>spyder-kernels</tt> module or the "
"right version of it installed ({1}). "
"Without this module is not possible for Spyder to "
"create a console for you.<br><br>"
"You can install it by activating your environment (if "
"necessary) and then running in a system terminal:"
"<pre>"
" <tt>{2}</tt>"
"</pre>"
"or"
"<pre>"
" <tt>{3}</tt>"
"</pre>").format(
pyexec,
SPYDER_KERNELS_VERSION_MSG,
SPYDER_KERNELS_CONDA,
SPYDER_KERNELS_PIP
)
msg = _(
"The Python environment or installation whose interpreter is "
"located at"
"<pre>"
" <tt>{0}</tt>"
"</pre>"
"doesn't have the <tt>spyder-kernels</tt> module or the right "
"version of it installed ({1}). Without this module is not "
"possible for Spyder to create a console for you.<br><br>"
"You can install it by activating your environment first (if "
"necessary) and then running in a system terminal:"
"<pre>"
" <tt>{2}</tt>"
"</pre>"
"or"
"<pre>"
" <tt>{3}</tt>"
"</pre>").format(
pyexec,
SPYDER_KERNELS_VERSION_MSG,
SPYDER_KERNELS_CONDA,
SPYDER_KERNELS_PIP
)

if not has_spyder_kernels:
self.show_kernel_error(msg)
return False
else:
return True
Expand Down
5 changes: 3 additions & 2 deletions spyder/plugins/ipythonconsole/widgets/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,9 @@ def interrupt_kernel(self):
super(ShellWidget, self).interrupt_kernel()
else:
self._append_html(
_("The kernel appears to be dead, so it can't be interrupted. "
"Please open a new console to keep working.")
_("<br><br>The kernel appears to be dead, so it can't be "
"interrupted. Please open a new console to keep "
"working.<br>")
)

def execute(self, source=None, hidden=False, interactive=False):
Expand Down

0 comments on commit eac428f

Please sign in to comment.