##// END OF EJS Templates
don't allow empty selection in selection widgets...
don't allow empty selection in selection widgets raises KeyError on failed lookup (in both directions)

File last commit:

r13390:79a70893
r15046:87d21c65
Show More
manager.py
186 lines | 6.0 KiB | text/x-python | PythonLexer
MinRK
rename widget to comm
r13195 """Base class to manage comms"""
#-----------------------------------------------------------------------------
# Copyright (C) 2013 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
hook up output for comm messages
r13202 import sys
MinRK
rename widget to comm
r13195 from IPython.config import LoggingConfigurable
from IPython.core.prompts import LazyEvaluate
from IPython.core.getipython import get_ipython
from IPython.utils.importstring import import_item
Thomas Kluyver
Fix reference to basestring in new Comm code
r13390 from IPython.utils.py3compat import string_types
MinRK
rename widget to comm
r13195 from IPython.utils.traitlets import Instance, Unicode, Dict, Any
from .comm import Comm
#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
def lazy_keys(dikt):
"""Return lazy-evaluated string representation of a dictionary's keys
Key list is only constructed if it will actually be used.
Used for debug-logging.
"""
return LazyEvaluate(lambda d: list(d.keys()))
MinRK
hook up output for comm messages
r13202 def with_output(method):
"""method decorator for ensuring output is handled properly in a message handler
- sets parent header before entering the method
MinRK
publish busy/idle when handling widget messages
r13203 - publishes busy/idle
MinRK
hook up output for comm messages
r13202 - flushes stdout/stderr after
"""
def method_with_output(self, stream, ident, msg):
MinRK
publish busy/idle when handling widget messages
r13203 parent = msg['header']
self.shell.set_parent(parent)
MinRK
set parent of status messages for comm_msgs
r13232 self.shell.kernel._publish_status('busy', parent)
MinRK
hook up output for comm messages
r13202 try:
return method(self, stream, ident, msg)
finally:
sys.stdout.flush()
sys.stderr.flush()
MinRK
set parent of status messages for comm_msgs
r13232 self.shell.kernel._publish_status('idle', parent)
MinRK
hook up output for comm messages
r13202
return method_with_output
MinRK
rename widget to comm
r13195 class CommManager(LoggingConfigurable):
"""Manager for Comms in the Kernel"""
shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
def _shell_default(self):
return get_ipython()
iopub_socket = Any()
def _iopub_socket_default(self):
MinRK
zmqshell has handle on Kernel
r13199 return self.shell.kernel.iopub_socket
MinRK
rename widget to comm
r13195 session = Instance('IPython.kernel.zmq.session.Session')
def _session_default(self):
if self.shell is None:
return
MinRK
zmqshell has handle on Kernel
r13199 return self.shell.kernel.session
MinRK
rename widget to comm
r13195
comms = Dict()
targets = Dict()
# Public APIs
MinRK
s/target/target_name
r13204 def register_target(self, target_name, f):
"""Register a callable f for a given target name
MinRK
rename widget to comm
r13195
MinRK
log exceptions in Comm handlers
r13227 f will be called with two arguments when a comm_open message is received with `target`:
- the Comm instance
- the `comm_open` message itself.
MinRK
rename widget to comm
r13195
f can be a Python callable or an import string for one.
"""
Thomas Kluyver
Fix reference to basestring in new Comm code
r13390 if isinstance(f, string_types):
MinRK
rename widget to comm
r13195 f = import_item(f)
MinRK
s/target/target_name
r13204 self.targets[target_name] = f
MinRK
rename widget to comm
r13195
MinRK
add unregister_target to CommManagers
r13226 def unregister_target(self, target_name, f):
"""Unregister a callable registered with register_target"""
return self.targets.pop(target_name);
MinRK
log exceptions in Comm handlers
r13227
MinRK
rename widget to comm
r13195 def register_comm(self, comm):
"""Register a new comm"""
comm_id = comm.comm_id
comm.shell = self.shell
comm.iopub_socket = self.iopub_socket
self.comms[comm_id] = comm
return comm_id
def unregister_comm(self, comm_id):
"""Unregister a comm, and close its counterpart"""
# unlike get_comm, this should raise a KeyError
comm = self.comms.pop(comm_id)
comm.close()
def get_comm(self, comm_id):
"""Get a comm with a particular id
Returns the comm if found, otherwise None.
This will not raise an error,
it will log messages if the comm cannot be found.
"""
if comm_id not in self.comms:
self.log.error("No such comm: %s", comm_id)
self.log.debug("Current comms: %s", lazy_keys(self.comms))
return
# call, because we store weakrefs
comm = self.comms[comm_id]
return comm
# Message handlers
MinRK
hook up output for comm messages
r13202 @with_output
MinRK
rename widget to comm
r13195 def comm_open(self, stream, ident, msg):
"""Handler for comm_open messages"""
content = msg['content']
comm_id = content['comm_id']
MinRK
s/target/target_name
r13204 target_name = content['target_name']
f = self.targets.get(target_name, None)
MinRK
rename widget to comm
r13195 comm = Comm(comm_id=comm_id,
shell=self.shell,
iopub_socket=self.iopub_socket,
primary=False,
)
MinRK
s/target/target_name
r13204 if f is None:
self.log.error("No such comm target registered: %s", target_name)
MinRK
s/destroy/close
r13196 comm.close()
MinRK
rename widget to comm
r13195 return
self.register_comm(comm)
MinRK
log exceptions in Comm handlers
r13227 try:
f(comm, msg)
except Exception:
self.log.error("Exception opening comm with target: %s", target_name, exc_info=True)
comm.close()
self.unregister_comm(comm_id)
MinRK
rename widget to comm
r13195
MinRK
hook up output for comm messages
r13202 @with_output
MinRK
rename widget to comm
r13195 def comm_msg(self, stream, ident, msg):
"""Handler for comm_msg messages"""
content = msg['content']
comm_id = content['comm_id']
comm = self.get_comm(comm_id)
if comm is None:
# no such comm
return
MinRK
log exceptions in Comm handlers
r13227 try:
comm.handle_msg(msg)
except Exception:
self.log.error("Exception in comm_msg for %s", comm_id, exc_info=True)
MinRK
rename widget to comm
r13195
MinRK
hook up output for comm messages
r13202 @with_output
MinRK
rename widget to comm
r13195 def comm_close(self, stream, ident, msg):
"""Handler for comm_close messages"""
content = msg['content']
comm_id = content['comm_id']
comm = self.get_comm(comm_id)
if comm is None:
# no such comm
MinRK
log exceptions in Comm handlers
r13227 self.log.debug("No such comm to close: %s", comm_id)
MinRK
rename widget to comm
r13195 return
del self.comms[comm_id]
MinRK
log exceptions in Comm handlers
r13227
try:
comm.handle_close(msg)
except Exception:
self.log.error("Exception handling comm_close for %s", comm_id, exc_info=True)
MinRK
rename widget to comm
r13195
__all__ = ['CommManager']