Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Add new API methods to the IPython console #18544

Merged
merged 5 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1137,8 +1137,7 @@ def test_connection_to_external_kernel(main_window, qtbot):
# Test with a generic kernel
km, kc = start_new_kernel()

main_window.ipyconsole.get_widget()._create_client_for_kernel(
kc.connection_file, None, None, None)
main_window.ipyconsole.create_client_for_kernel(kc.connection_file)
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(
lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)
Expand All @@ -1155,8 +1154,7 @@ def test_connection_to_external_kernel(main_window, qtbot):

# Test with a kernel from Spyder
spykm, spykc = start_new_kernel(spykernel=True)
main_window.ipyconsole.get_widget()._create_client_for_kernel(
spykc.connection_file, None, None, None)
main_window.ipyconsole.create_client_for_kernel(spykc.connection_file)
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(
lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)
Expand Down
81 changes: 61 additions & 20 deletions spyder/plugins/ipythonconsole/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import os.path as osp

# Third party imports
from qtpy.QtCore import Signal
from qtpy.QtCore import Signal, Slot

# Local imports
from spyder.api.plugins import Plugins, SpyderDockablePlugin
Expand Down Expand Up @@ -329,6 +329,12 @@ def on_projects_available(self):
projects.sig_project_loaded.connect(self._on_project_loaded)
projects.sig_project_closed.connect(self._on_project_closed)

@on_plugin_available(plugin=Plugins.WorkingDirectory)
def on_working_directory_available(self):
working_directory = self.get_plugin(Plugins.WorkingDirectory)
working_directory.sig_current_directory_changed.connect(
self._set_working_directory)

@on_plugin_teardown(plugin=Plugins.Preferences)
def on_preferences_teardown(self):
# Register conf page
Expand Down Expand Up @@ -371,6 +377,12 @@ def on_projects_teardown(self):
projects.sig_project_loaded.disconnect(self._on_project_loaded)
projects.sig_project_closed.disconnect(self._on_project_closed)

@on_plugin_teardown(plugin=Plugins.WorkingDirectory)
def on_working_directory_teardown(self):
working_directory = self.get_plugin(Plugins.WorkingDirectory)
working_directory.sig_current_directory_changed.disconnect(
self._set_working_directory)

def update_font(self):
"""Update font from Preferences"""
font = self.get_font()
Expand Down Expand Up @@ -425,11 +437,10 @@ def _remove_old_std_files(self):
except Exception:
pass

def _get_working_directory(self):
"""Get current working directory from its plugin."""
workdir = self.get_plugin(Plugins.WorkingDirectory)
if workdir:
return workdir.get_workdir()
@Slot(str)
def _set_working_directory(self, new_dir):
"""Set current working directory on the main widget."""
self.get_widget().set_working_directory(new_dir)

# ---- Public API
# -------------------------------------------------------------------------
Expand All @@ -452,7 +463,6 @@ def register_spyder_kernel_call_handler(self, handler_id, handler):
Returns
-------
None.

"""
self.get_widget().register_spyder_kernel_call_handler(
handler_id, handler)
Expand All @@ -470,7 +480,6 @@ def unregister_spyder_kernel_call_handler(self, handler_id):
Returns
-------
None.

"""
self.get_widget().unregister_spyder_kernel_call_handler(handler_id)

Expand All @@ -491,6 +500,23 @@ def get_current_shellwidget(self):
"""Return the shellwidget of the current client"""
return self.get_widget().get_current_shellwidget()

def rename_client_tab(self, client, given_name):
"""
Rename a client's tab.

Parameters
----------
client: spyder.plugins.ipythonconsole.widgets.client.ClientWidget
Client to rename.
given_name: str
New name to be given to the client's tab.

Returns
-------
None.
"""
self.get_widget().rename_client_tab(client, given_name)

def create_new_client(self, give_focus=True, filename='', is_cython=False,
is_pylab=False, is_sympy=False, given_name=None):
"""
Expand Down Expand Up @@ -519,7 +545,6 @@ def create_new_client(self, give_focus=True, filename='', is_cython=False,
Returns
-------
None.

"""
self.get_widget().create_new_client(
give_focus=give_focus,
Expand All @@ -543,10 +568,36 @@ def create_client_for_file(self, filename, is_cython=False):
Returns
-------
None.

"""
self.get_widget().create_client_for_file(filename, is_cython=is_cython)

def create_client_for_kernel(self, connection_file, hostname=None,
sshkey=None, password=None):
"""
Create a client connected to an existing kernel.

Parameters
----------
connection_file: str
Json file that has the kernel's connection info.
hostname: str, optional
Name or IP address of the remote machine where the kernel was
started. When this is provided, it's also necessary to pass either
the ``sshkey`` or ``password`` arguments.
sshkey: str, optional
SSH key file to connect to the remote machine where the kernel is
running.
password: str, optional
Password to authenticate to the remote machine where the kernel is
running.

Returns
-------
None.
"""
self.get_widget().create_client_for_kernel(
connection_file, hostname, sshkey, password)

def get_client_for_file(self, filename):
"""Get client associated with a given file name."""
return self.get_widget().get_client_for_file(filename)
Expand Down Expand Up @@ -599,7 +650,6 @@ def run_script(self, filename, wdir, args, debug, post_mortem,
Returns
-------
None.

"""
self.get_widget().run_script(
filename,
Expand Down Expand Up @@ -639,7 +689,6 @@ def run_cell(self, code, cell_name, filename, run_cell_copy,
Returns
-------
None.

"""
self.get_widget().run_cell(
code, cell_name, filename, run_cell_copy, focus_to_editor,
Expand Down Expand Up @@ -669,7 +718,6 @@ def debug_cell(self, code, cell_name, filename, run_cell_copy,
Returns
-------
None.

"""
self.get_widget().debug_cell(code, cell_name, filename, run_cell_copy,
focus_to_editor)
Expand All @@ -692,7 +740,6 @@ def execute_code(self, lines, current_client=True, clear_variables=False):
Returns
-------
None.

"""
self.get_widget().execute_code(
lines,
Expand Down Expand Up @@ -734,7 +781,6 @@ def pdb_execute_command(self, command):
Returns
-------
None.

"""
self.get_widget().pdb_execute_command(command)

Expand All @@ -745,7 +791,6 @@ def print_debug_file_msg(self):
Returns
-------
None.

"""
self.get_widget().print_debug_file_msg()

Expand All @@ -762,7 +807,6 @@ def set_current_client_working_directory(self, directory):
Returns
-------
None.

"""
self.get_widget().set_current_client_working_directory(directory)

Expand All @@ -779,7 +823,6 @@ def set_working_directory(self, dirname):
Returns
-------
None.

"""
self.get_widget().set_working_directory(dirname)

Expand All @@ -804,7 +847,6 @@ def update_path(self, path_dict, new_path_dict):
Returns
-------
None.

"""
self.get_widget().update_path(path_dict, new_path_dict)

Expand All @@ -828,7 +870,6 @@ def restart_kernel(self):
Returns
-------
None.

"""
self.get_widget().restart_kernel()

Expand Down
22 changes: 8 additions & 14 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# Local imports
from spyder.app.cli_options import get_options
from spyder.config.base import (
get_home_dir, running_in_ci, running_in_ci_with_conda)
running_in_ci, running_in_ci_with_conda)
from spyder.config.gui import get_color_scheme
from spyder.config.manager import CONF
from spyder.py3compat import PY2, to_text_string
Expand Down Expand Up @@ -219,9 +219,6 @@ def __getattr__(self, attr):
is_cython=is_cython)
window.setCentralWidget(console.get_widget())

# Return working directory from the plugin
console._get_working_directory = lambda: get_home_dir()

# Set exclamation mark to True
configuration.set('ipython_console', 'pdb_use_exclamation_mark', True)

Expand Down Expand Up @@ -554,7 +551,7 @@ def test_cython_client(ipyconsole, qtbot):
def test_tab_rename_for_slaves(ipyconsole, qtbot):
"""Test slave clients are renamed correctly."""
cf = ipyconsole.get_current_client().connection_file
ipyconsole.get_widget()._create_client_for_kernel(cf, None, None, None)
ipyconsole.create_client_for_kernel(cf)
qtbot.waitUntil(lambda: len(ipyconsole.get_clients()) == 2)

# Rename slave
Expand Down Expand Up @@ -1217,7 +1214,7 @@ def test_load_kernel_file_from_id(ipyconsole, qtbot):
connection_file = osp.basename(client.connection_file)
id_ = connection_file.split('kernel-')[-1].split('.json')[0]

ipyconsole.get_widget()._create_client_for_kernel(id_, None, None, None)
ipyconsole.create_client_for_kernel(id_)
qtbot.waitUntil(lambda: len(ipyconsole.get_clients()) == 2)

new_client = ipyconsole.get_clients()[1]
Expand All @@ -1236,7 +1233,7 @@ def test_load_kernel_file_from_location(ipyconsole, qtbot, tmpdir):
connection_file = to_text_string(tmpdir.join(fname))
shutil.copy2(client.connection_file, connection_file)

ipyconsole.get_widget()._create_client_for_kernel(connection_file, None, None, None)
ipyconsole.create_client_for_kernel(connection_file)
qtbot.waitUntil(lambda: len(ipyconsole.get_clients()) == 2)

assert len(ipyconsole.get_clients()) == 2
Expand All @@ -1251,8 +1248,7 @@ def test_load_kernel_file(ipyconsole, qtbot, tmpdir):
shell = ipyconsole.get_current_shellwidget()
client = ipyconsole.get_current_client()

ipyconsole.get_widget()._create_client_for_kernel(
client.connection_file, None, None, None)
ipyconsole.create_client_for_kernel(client.connection_file)
qtbot.waitUntil(lambda: len(ipyconsole.get_clients()) == 2)

new_client = ipyconsole.get_clients()[1]
Expand Down Expand Up @@ -1334,8 +1330,7 @@ def test_stderr_file_is_removed_two_kernels(ipyconsole, qtbot, monkeypatch):
client = ipyconsole.get_current_client()

# New client with the same kernel
ipyconsole.get_widget()._create_client_for_kernel(
client.connection_file, None, None, None)
ipyconsole.create_client_for_kernel(client.connection_file)
assert len(ipyconsole.get_widget().get_related_clients(client)) == 1
other_client = ipyconsole.get_widget().get_related_clients(client)[0]
assert client.stderr_obj.filename == other_client.stderr_obj.filename
Expand All @@ -1356,8 +1351,7 @@ def test_stderr_file_remains_two_kernels(ipyconsole, qtbot, monkeypatch):
client = ipyconsole.get_current_client()

# New client with the same kernel
ipyconsole.get_widget()._create_client_for_kernel(
client.connection_file, None, None, None)
ipyconsole.create_client_for_kernel(client.connection_file)

assert len(ipyconsole.get_widget().get_related_clients(client)) == 1
other_client = ipyconsole.get_widget().get_related_clients(client)[0]
Expand Down Expand Up @@ -2287,7 +2281,7 @@ def get_cwd_of_new_client():

# Simulate a specific directory
cwd_dir = str(tmpdir.mkdir('ipyconsole_cwd_test'))
ipyconsole._get_working_directory = lambda: cwd_dir
ipyconsole.get_widget().set_working_directory(cwd_dir)

# Get cwd of new client and assert is the expected one
assert get_cwd_of_new_client() == cwd_dir
Expand Down
Loading