diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 56aea6d..783bd5e 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -523,7 +523,6 @@ class InteractiveShell(SingletonConfigurable): self.init_pdb() self.init_extension_manager() self.init_payload() - self.init_comms() self.hooks.late_startup_hook() self.events.trigger('shell_initialized', self) atexit.register(self.atexit_operations) @@ -2419,14 +2418,6 @@ class InteractiveShell(SingletonConfigurable): self.configurables.append(self.payload_manager) #------------------------------------------------------------------------- - # Things related to widgets - #------------------------------------------------------------------------- - - def init_comms(self): - # not implemented in the base class - pass - - #------------------------------------------------------------------------- # Things related to the prefilter #------------------------------------------------------------------------- diff --git a/IPython/html/widgets/tests/test_interaction.py b/IPython/html/widgets/tests/test_interaction.py index 6f04bee..e891c96 100644 --- a/IPython/html/widgets/tests/test_interaction.py +++ b/IPython/html/widgets/tests/test_interaction.py @@ -22,6 +22,9 @@ from IPython.utils.py3compat import annotate class DummyComm(Comm): comm_id = 'a-b-c-d' + def open(self, *args, **kwargs): + pass + def send(self, *args, **kwargs): pass diff --git a/IPython/kernel/comm/comm.py b/IPython/kernel/comm/comm.py index 27231a3..ec3c851 100644 --- a/IPython/kernel/comm/comm.py +++ b/IPython/kernel/comm/comm.py @@ -6,7 +6,7 @@ import uuid from IPython.config import LoggingConfigurable -from IPython.core.getipython import get_ipython +from IPython.kernel.zmq.kernelbase import Kernel from IPython.utils.jsonutil import json_clean from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any @@ -18,6 +18,9 @@ class Comm(LoggingConfigurable): shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True) kernel = Instance('IPython.kernel.zmq.kernelbase.Kernel') + def _kernel_default(self): + if Kernel.initialized(): + return Kernel.instance() iopub_socket = Any() def _iopub_socket_default(self): @@ -55,16 +58,15 @@ class Comm(LoggingConfigurable): def _publish_msg(self, msg_type, data=None, metadata=None, **keys): """Helper for sending a comm message on IOPub""" - if self.session is not None: - data = {} if data is None else data - metadata = {} if metadata is None else metadata - content = json_clean(dict(data=data, comm_id=self.comm_id, **keys)) - self.session.send(self.iopub_socket, msg_type, - content, - metadata=json_clean(metadata), - parent=self.kernel._parent_header, - ident=self.topic, - ) + data = {} if data is None else data + metadata = {} if metadata is None else metadata + content = json_clean(dict(data=data, comm_id=self.comm_id, **keys)) + self.session.send(self.iopub_socket, msg_type, + content, + metadata=json_clean(metadata), + parent=self.kernel._parent_header, + ident=self.topic, + ) def __del__(self): """trigger close on gc""" @@ -76,10 +78,13 @@ class Comm(LoggingConfigurable): """Open the frontend-side version of this comm""" if data is None: data = self._open_data + comm_manager = getattr(self.kernel, 'comm_manager', None) + if comm_manager is None: + raise RuntimeError("Comms cannot be opened without a kernel " + "and a comm_manager attached to that kernel.") + + comm_manager.register_comm(self) self._closed = False - ip = get_ipython() - if hasattr(ip, 'comm_manager'): - ip.comm_manager.register_comm(self) self._publish_msg('comm_open', data, metadata, target_name=self.target_name) def close(self, data=None, metadata=None): @@ -90,9 +95,7 @@ class Comm(LoggingConfigurable): if data is None: data = self._close_data self._publish_msg('comm_close', data, metadata) - ip = get_ipython() - if hasattr(ip, 'comm_manager'): - ip.comm_manager.unregister_comm(self) + self.kernel.comm_manager.unregister_comm(self) self._closed = True def send(self, data=None, metadata=None): diff --git a/IPython/kernel/zmq/ipkernel.py b/IPython/kernel/zmq/ipkernel.py index 93915b5..7354e65 100644 --- a/IPython/kernel/zmq/ipkernel.py +++ b/IPython/kernel/zmq/ipkernel.py @@ -10,6 +10,7 @@ from IPython.utils.tokenutil import token_at_cursor from IPython.utils.traitlets import Instance, Type, Any from IPython.utils.decorators import undoc +from ..comm import CommManager from .kernelbase import Kernel as KernelBase from .serialize import serialize_object, unpack_apply_message from .zmqshell import ZMQInteractiveShell @@ -55,10 +56,12 @@ class IPythonKernel(KernelBase): # TMP - hack while developing self.shell._reply_content = None + self.comm_manager = CommManager(shell=self.shell, parent=self, + kernel=self) + self.shell.configurables.append(self.comm_manager) comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ] - comm_manager = self.shell.comm_manager for msg_type in comm_msg_types: - self.shell_handlers[msg_type] = getattr(comm_manager, msg_type) + self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) # Kernel info fields implementation = 'ipython' diff --git a/IPython/kernel/zmq/kernelapp.py b/IPython/kernel/zmq/kernelapp.py index 6bfdc52..a58f19b 100644 --- a/IPython/kernel/zmq/kernelapp.py +++ b/IPython/kernel/zmq/kernelapp.py @@ -306,7 +306,7 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, shell_stream = ZMQStream(self.shell_socket) control_stream = ZMQStream(self.control_socket) - kernel_factory = self.kernel_class + kernel_factory = self.kernel_class.instance kernel = kernel_factory(parent=self, session=self.session, shell_streams=[shell_stream, control_stream], diff --git a/IPython/kernel/zmq/kernelbase.py b/IPython/kernel/zmq/kernelbase.py index 2fa4740..30677ca 100755 --- a/IPython/kernel/zmq/kernelbase.py +++ b/IPython/kernel/zmq/kernelbase.py @@ -19,7 +19,7 @@ import zmq from zmq.eventloop import ioloop from zmq.eventloop.zmqstream import ZMQStream -from IPython.config.configurable import Configurable +from IPython.config.configurable import SingletonConfigurable from IPython.core.error import StdinNotImplementedError from IPython.core import release from IPython.utils import py3compat @@ -32,7 +32,7 @@ from IPython.utils.traitlets import ( from .session import Session -class Kernel(Configurable): +class Kernel(SingletonConfigurable): #--------------------------------------------------------------------------- # Kernel interface diff --git a/IPython/kernel/zmq/zmqshell.py b/IPython/kernel/zmq/zmqshell.py index 263db9a..3a4effd 100644 --- a/IPython/kernel/zmq/zmqshell.py +++ b/IPython/kernel/zmq/zmqshell.py @@ -49,7 +49,6 @@ from IPython.utils.warn import error from IPython.kernel.zmq.displayhook import ZMQShellDisplayHook from IPython.kernel.zmq.datapub import ZMQDataPublisher from IPython.kernel.zmq.session import extract_header -from IPython.kernel.comm import CommManager from .session import Session #----------------------------------------------------------------------------- @@ -563,11 +562,6 @@ class ZMQInteractiveShell(InteractiveShell): super(ZMQInteractiveShell, self).init_magics() self.register_magics(KernelMagics) self.magics_manager.register_alias('ed', 'edit') - - def init_comms(self): - self.comm_manager = CommManager(shell=self, parent=self, - kernel=self.kernel) - self.configurables.append(self.comm_manager) InteractiveShellABC.register(ZMQInteractiveShell)