diff --git a/jupyter_console/completer.py b/jupyter_console/completer.py index d0b7b9a..6a38a6a 100644 --- a/jupyter_console/completer.py +++ b/jupyter_console/completer.py @@ -7,6 +7,16 @@ from traitlets.config import Configurable from traitlets import Float +import jupyter_client + + +# jupyter_client 7.0+ has async channel methods that we expect to be sync here +if jupyter_client.version_info >= (7,): + from jupyter_client.utils import run_sync +else: + run_sync = lambda x: x + + class ZMQCompleter(Configurable): """Client-side completion machinery. @@ -31,7 +41,7 @@ def complete_request(self, code, cursor_pos): cursor_pos=cursor_pos, ) - msg = self.client.shell_channel.get_msg(timeout=self.timeout) + msg = run_sync(self.client.shell_channel.get_msg)(timeout=self.timeout) if msg['parent_header']['msg_id'] == msg_id: return msg['content'] diff --git a/jupyter_console/ptshell.py b/jupyter_console/ptshell.py index a9daeed..31f424d 100644 --- a/jupyter_console/ptshell.py +++ b/jupyter_console/ptshell.py @@ -76,6 +76,18 @@ from pygments.util import ClassNotFound from pygments.token import Token +import jupyter_client + + +# jupyter_client 7.0+ has async channel methods that we expect to be sync here +# also, `block` was removed from `get_msg()` +if jupyter_client._version.version_info[0] >= 7: + from jupyter_client.utils import run_sync + JUPYTER_CLIENT_7 = True +else: + run_sync = lambda x: x + JUPYTER_CLIENT_7 = False + def ask_yes_no(prompt, default=None, interrupt=None): """Asks a question and returns a boolean (y/n) answer. @@ -705,8 +717,8 @@ def run_cell(self, cell, store_history=True): return # flush stale replies, which could have been ignored, due to missed heartbeats - while self.client.shell_channel.msg_ready(): - self.client.shell_channel.get_msg() + while run_sync(self.client.shell_channel.msg_ready)(): + run_sync(self.client.shell_channel.get_msg)() # execute takes 'hidden', which is the inverse of store_hist msg_id = self.client.execute(cell, not store_history) @@ -739,7 +751,10 @@ def run_cell(self, cell, store_history=True): #----------------- def handle_execute_reply(self, msg_id, timeout=None): - msg = self.client.shell_channel.get_msg(block=False, timeout=timeout) + kwargs = {"timeout": timeout} + if not JUPYTER_CLIENT_7: + kwargs["block"] = False + msg = run_sync(self.client.shell_channel.get_msg)(**kwargs) if msg["parent_header"].get("msg_id", None) == msg_id: self.handle_iopub(msg_id) @@ -778,7 +793,10 @@ def handle_is_complete_reply(self, msg_id, timeout=None): ## Get the is_complete response: msg = None try: - msg = self.client.shell_channel.get_msg(block=True, timeout=timeout) + kwargs = {"timeout": timeout} + if not JUPYTER_CLIENT_7: + kwargs["block"] = True + msg = run_sync(self.client.shell_channel.get_msg)(**kwargs) except Empty: warn('The kernel did not respond to an is_complete_request. ' 'Setting `use_kernel_is_complete` to False.') @@ -849,8 +867,8 @@ def handle_iopub(self, msg_id=''): It only displays output that is caused by this session. """ - while self.client.iopub_channel.msg_ready(): - sub_msg = self.client.iopub_channel.get_msg() + while run_sync(self.client.iopub_channel.msg_ready)(): + sub_msg = run_sync(self.client.iopub_channel.get_msg)() msg_type = sub_msg['header']['msg_type'] # Update execution_count in case it changed in another session @@ -1003,7 +1021,7 @@ def handle_image_callable(self, data, mime): def handle_input_request(self, msg_id, timeout=0.1): """ Method to capture raw_input """ - req = self.client.stdin_channel.get_msg(timeout=timeout) + req = run_sync(self.client.stdin_channel.get_msg)(timeout=timeout) # in case any iopub came while we were waiting: self.handle_iopub(msg_id) if msg_id == req["parent_header"].get("msg_id"): @@ -1032,6 +1050,6 @@ def double_int(sig, frame): # only send stdin reply if there *was not* another request # or execution finished while we were reading. - if not (self.client.stdin_channel.msg_ready() or - self.client.shell_channel.msg_ready()): + if not (run_sync(self.client.stdin_channel.msg_ready)() or + run_sync(self.client.shell_channel.msg_ready)()): self.client.input(raw_data)