diff --git a/IPython/kernel/blocking/channels.py b/IPython/kernel/blocking/channels.py index 512070d..36bb78a 100644 --- a/IPython/kernel/blocking/channels.py +++ b/IPython/kernel/blocking/channels.py @@ -143,21 +143,6 @@ class BlockingShellChannel(ZMQSocketChannel): def start(self): self.socket = make_stdin_socket(self.context, self.session.bsession, self.address) - def _handle_kernel_info_reply(self, msg): - """handle kernel info reply - - sets protocol adaptation version - """ - adapt_version = int(msg['content']['protocol_version'].split('.')[0]) - if adapt_version != major_protocol_version: - self.session.adapt_version = adapt_version - - def _recv(self, **kwargs): - # Listen for kernel_info_reply message to do protocol adaptation - msg = ZMQSocketChannel._recv(self, **kwargs) - if msg['msg_type'] == 'kernel_info_reply': - self._handle_kernel_info_reply(msg) - return msg class BlockingIOPubChannel(ZMQSocketChannel): """The iopub channel which listens for messages that the kernel publishes. @@ -169,9 +154,6 @@ class BlockingIOPubChannel(ZMQSocketChannel): class BlockingStdInChannel(ZMQSocketChannel): """The stdin channel to handle raw_input requests that the kernel makes.""" - msg_queue = None - proxy_methods = ['input'] - def start(self): self.socket = make_stdin_socket(self.context, self.session.bsession, self.address) diff --git a/IPython/kernel/blocking/client.py b/IPython/kernel/blocking/client.py index 971cf0c..c2c7496 100644 --- a/IPython/kernel/blocking/client.py +++ b/IPython/kernel/blocking/client.py @@ -2,16 +2,13 @@ Useful for test suites and blocking terminal interfaces. """ -#----------------------------------------------------------------------------- -# Copyright (C) 2013 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING.txt, distributed as part of this software. -#----------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +try: + from queue import Empty # Python 3 +except ImportError: + from Queue import Empty # Python 2 from IPython.utils.traitlets import Type from IPython.kernel.client import KernelClient @@ -20,11 +17,22 @@ from .channels import ( BlockingShellChannel, BlockingStdInChannel ) -#----------------------------------------------------------------------------- -# Blocking kernel manager -#----------------------------------------------------------------------------- - class BlockingKernelClient(KernelClient): + def wait_for_ready(self): + # Wait for kernel info reply on shell channel + while True: + msg = self.shell_channel.get_msg(block=True) + if msg['msg_type'] == 'kernel_info_reply': + self._handle_kernel_info_reply(msg) + break + + # Flush IOPub channel + while True: + try: + msg = self.iopub_channel.get_msg(block=True, timeout=0.2) + print(msg['msg_type']) + except Empty: + break # The classes to use for the various channels shell_channel_class = Type(BlockingShellChannel) diff --git a/IPython/kernel/client.py b/IPython/kernel/client.py index bd1d16d..729a331 100644 --- a/IPython/kernel/client.py +++ b/IPython/kernel/client.py @@ -4,7 +4,7 @@ # Distributed under the terms of the Modified BSD License. from __future__ import absolute_import -from IPython.kernel.channels import validate_string_dict +from IPython.kernel.channels import validate_string_dict, major_protocol_version from IPython.utils.py3compat import string_types import zmq @@ -90,6 +90,7 @@ class KernelClient(ConnectionFileMixin): """ if shell: self.shell_channel.start() + self.kernel_info() if iopub: self.iopub_channel.start() if stdin: @@ -327,6 +328,15 @@ class KernelClient(ConnectionFileMixin): self.shell_channel._queue_send(msg) return msg['header']['msg_id'] + def _handle_kernel_info_reply(self, msg): + """handle kernel info reply + + sets protocol adaptation version + """ + adapt_version = int(msg['content']['protocol_version'].split('.')[0]) + if adapt_version != major_protocol_version: + self.session.adapt_version = adapt_version + def shutdown(self, restart=False): """Request an immediate kernel shutdown. diff --git a/IPython/kernel/manager.py b/IPython/kernel/manager.py index 857bd82..6b125a2 100644 --- a/IPython/kernel/manager.py +++ b/IPython/kernel/manager.py @@ -421,17 +421,8 @@ def start_new_kernel(startup_timeout=60, kernel_name='python', **kwargs): km.start_kernel(**kwargs) kc = km.client() kc.start_channels() + kc.wait_for_ready() - kc.kernel_info() - kc.get_shell_msg(block=True, timeout=startup_timeout) - - # Flush channels - for channel in (kc.shell_channel, kc.iopub_channel): - while True: - try: - channel.get_msg(block=True, timeout=0.1) - except Empty: - break return km, kc @contextmanager diff --git a/IPython/kernel/zmq/tests/test_embed_kernel.py b/IPython/kernel/zmq/tests/test_embed_kernel.py index 45f543f..977c22c 100644 --- a/IPython/kernel/zmq/tests/test_embed_kernel.py +++ b/IPython/kernel/zmq/tests/test_embed_kernel.py @@ -92,6 +92,7 @@ def setup_kernel(cmd): client = BlockingKernelClient(connection_file=connection_file) client.load_connection_file() client.start_channels() + client.wait_for_ready() try: yield client diff --git a/IPython/qt/client.py b/IPython/qt/client.py index 119a305..d4deb73 100644 --- a/IPython/qt/client.py +++ b/IPython/qt/client.py @@ -366,6 +366,14 @@ StdInChannelABC.register(QtStdInChannel) class QtKernelClient(QtKernelClientMixin, KernelClient): """ A KernelClient that provides signals and slots. """ + def start_channels(self, shell=True, iopub=True, stdin=True, hb=True): + if shell: + self.shell_channel.kernel_info_reply.connect(self._handle_kernel_info_reply) + super(QtKernelClient, self).start_channels(shell, iopub, stdin, hb) + + def _handle_kernel_info_reply(self, msg): + super(QtKernelClient, self)._handle_kernel_info_reply(msg) + self.shell_channel.kernel_info_reply.disconnect(self._handle_kernel_info_reply) iopub_channel_class = Type(QtIOPubChannel) shell_channel_class = Type(QtShellChannel)