Skip to content

Commit

Permalink
Backport PR #22501 on branch 6.x (PR: Show banner when the kernel is …
Browse files Browse the repository at this point in the history
…ready (IPython console) ) (#22535)

Co-authored-by: Carlos Cordoba <[email protected]>
  • Loading branch information
meeseeksmachine and ccordoba12 authored Sep 19, 2024
1 parent 934be48 commit 994e499
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 22 deletions.
2 changes: 1 addition & 1 deletion spyder/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def running_in_ci_with_conda():
def running_in_binder():
"""Return True if currently running in Binder."""
return (
os.environ.get("BINDER_REPO_URL")
bool(os.environ.get("BINDER_REPO_URL"))
and "spyder-ide/binder-environments" in os.environ["BINDER_REPO_URL"]
)

Expand Down
5 changes: 5 additions & 0 deletions spyder/plugins/ipythonconsole/comms/kernelcomm.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ def open_comm(self, kernel_client):
"""Open comm through the kernel client."""
self.kernel_client = kernel_client
try:
logger.debug(
f"Opening kernel comm for "
f"{'<' + repr(kernel_client).split('.')[-1]}"
)

self._register_comm(
# Create new comm and send the highest protocol
kernel_client.comm_manager.new_comm(self._comm_name)
Expand Down
23 changes: 14 additions & 9 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,28 @@ def test_banners(ipyconsole, qtbot):
shell = ipyconsole.get_current_shellwidget()
control = shell._control

# Long banner
# Check long banner (the default)
text = control.toPlainText().splitlines()
if "Update LANGUAGE_CODES" in text[0]:
text = text[1:]
while not text[0].strip():
text = text[1:]
py_ver = sys.version.splitlines()[0].strip()
assert py_ver in text[0] # Python version in first line
assert 'license' in text[1] # 'license' mention in second line
assert '' == text[2] # Third line is empty
assert ipy_release.version in text[3] # Fourth line is IPython

# Short banner
short_banner = shell.short_banner()
# Check short banner for a new console
ipyconsole.set_conf("show_banner", False)
ipyconsole.create_new_client()
shell = ipyconsole.get_current_shellwidget()
qtbot.waitUntil(
lambda: shell.spyder_kernel_ready and shell._prompt_html is not None,
timeout=SHELL_TIMEOUT
)

py_ver = sys.version.split(' ')[0]
expected = 'Python %s -- IPython %s' % (py_ver, ipy_release.version)
assert expected == short_banner
expected = (
f"Python {py_ver} -- IPython {ipy_release.version}\n\n" + "In [1]: "
)
assert expected == shell._control.toPlainText()


@flaky(max_runs=3)
Expand Down
41 changes: 29 additions & 12 deletions spyder/plugins/ipythonconsole/widgets/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"""

# Standard library imports
import logging
import os
import os.path as osp
import time
Expand Down Expand Up @@ -45,8 +46,11 @@
from spyder.widgets.helperwidgets import MessageCheckBox


logger = logging.getLogger(__name__)

MODULES_FAQ_URL = (
"https://docs.spyder-ide.org/5/faq.html#using-packages-installer")
"https://docs.spyder-ide.org/5/faq.html#using-packages-installer"
)


class ShellWidget(NamepaceBrowserWidget, HelpWidget, DebuggingWidget,
Expand Down Expand Up @@ -182,6 +186,7 @@ def __init__(
self._kernel_configuration = {}
self.is_kernel_configured = False
self._init_kernel_setup = False
self._is_banner_shown = False

if handlers is None:
handlers = {}
Expand All @@ -199,9 +204,6 @@ def __init__(
self._execute_queue = []
self.executed.connect(self.pop_execute_queue)

# To show the console banner on first prompt
self.sig_prompt_ready.connect(self._show_banner)

# Show a message in our installers to explain users how to use
# modules that don't come with them.
self.show_modules_message = is_conda_based_app()
Expand Down Expand Up @@ -317,6 +319,7 @@ def handle_kernel_is_ready(self):
KernelConnectionState.SpyderKernelReady
):
self.setup_spyder_kernel()
self._show_banner()

def handle_kernel_connection_error(self):
"""An error occurred when connecting to the kernel."""
Expand Down Expand Up @@ -796,7 +799,7 @@ def long_banner(self):
)

banner = ''.join(banner_parts)
except CommError:
except (CommError, TimeoutError):
banner = ""

# Pylab additions
Expand Down Expand Up @@ -834,8 +837,8 @@ def short_banner(self):
env_info = self.get_pythonenv_info()
py_ver = env_info['python_version']
ipy_ver = env_info['ipython_version']
banner = f'Python {py_ver} -- IPython {ipy_ver}'
except CommError:
banner = f'Python {py_ver} -- IPython {ipy_ver}\n'
except (CommError, TimeoutError):
banner = ""

return banner
Expand Down Expand Up @@ -1182,11 +1185,17 @@ def _save_clipboard_indentation(self):

def _show_banner(self):
"""Show banner before first prompt."""
# Don't show banner for external kernels
if self.is_external_kernel and not self.is_remote():
return ""
if (
# Don't show banner for external but local kernels
self.is_external_kernel and not self.is_remote()
# Don't show it if it was already shown
or self._is_banner_shown
):
return

logger.debug(f"Showing banner for {self}")

# Detect what kind of banner we want to show
# Check what kind of banner we want to show
show_banner_o = self.additional_options['show_banner']
if show_banner_o:
banner = self.long_banner()
Expand All @@ -1199,7 +1208,7 @@ def _show_banner(self):
self._insert_plain_text(cursor, banner)

# Only do this once
self.sig_prompt_ready.disconnect(self._show_banner)
self._is_banner_shown = True

# ---- Private API (overrode by us)
def _event_filter_console_keypress(self, event):
Expand Down Expand Up @@ -1465,3 +1474,11 @@ def focusOutEvent(self, event):
"""Reimplement Qt method to send focus change notification"""
self.sig_focus_changed.emit()
return super(ShellWidget, self).focusOutEvent(event)

# ---- Python methods
def __repr__(self):
# Handy repr for logging.
# Solution from https://stackoverflow.com/a/121508/438386
return (
"<" + self.__class__.__name__ + " object at " + hex(id(self)) + ">"
)
2 changes: 2 additions & 0 deletions spyder/plugins/ipythonconsole/widgets/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ def update_matplotlib_gui(self, gui, shellwidget=None):
# -------------------------------------------------------------------------
def update_status(self, gui):
"""Update interactive state."""
logger.debug(f"Setting Matplotlib backend to {gui}")

if self._interactive_gui is None and gui != "inline":
self._interactive_gui = gui
self._gui = gui
Expand Down

0 comments on commit 994e499

Please sign in to comment.