ipkernel.py
131 lines
| 4.6 KiB
| text/x-python
|
PythonLexer
epatters
|
r8471 | """ An in-process kernel. """ | ||
epatters
|
r8408 | |||
#----------------------------------------------------------------------------- | ||||
# Copyright (C) 2012 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 | ||||
#----------------------------------------------------------------------------- | ||||
epatters
|
r8411 | # Standard library imports | ||
from contextlib import contextmanager | ||||
import logging | ||||
import sys | ||||
epatters
|
r8408 | # Local imports. | ||
epatters
|
r8471 | from IPython.inprocess.socket import DummySocket | ||
epatters
|
r8411 | from IPython.utils.jsonutil import json_clean | ||
from IPython.utils.traitlets import Any, Instance, List | ||||
epatters
|
r8408 | from IPython.zmq.ipkernel import Kernel | ||
#----------------------------------------------------------------------------- | ||||
# Main kernel class | ||||
#----------------------------------------------------------------------------- | ||||
epatters
|
r8471 | class InProcessKernel(Kernel): | ||
epatters
|
r8411 | |||
#------------------------------------------------------------------------- | ||||
epatters
|
r8471 | # InProcessKernel interface | ||
epatters
|
r8411 | #------------------------------------------------------------------------- | ||
frontends = List( | ||||
epatters
|
r8471 | Instance('IPython.inprocess.kernelmanager.InProcessKernelManager')) | ||
epatters
|
r8411 | |||
raw_input_str = Any() | ||||
stdout = Any() | ||||
stderr = Any() | ||||
#------------------------------------------------------------------------- | ||||
# Kernel interface | ||||
#------------------------------------------------------------------------- | ||||
shell_streams = List() | ||||
control_stream = Any() | ||||
iopub_socket = Instance(DummySocket, ()) | ||||
stdin_socket = Instance(DummySocket, ()) | ||||
def __init__(self, **traits): | ||||
# When an InteractiveShell is instantiated by our base class, it binds | ||||
# the current values of sys.stdout and sys.stderr. | ||||
with self._redirected_io(): | ||||
epatters
|
r8471 | super(InProcessKernel, self).__init__(**traits) | ||
epatters
|
r8411 | |||
self.iopub_socket.on_trait_change(self._io_dispatch, 'message_sent') | ||||
def execute_request(self, stream, ident, parent): | ||||
""" Override for temporary IO redirection. """ | ||||
with self._redirected_io(): | ||||
epatters
|
r8471 | super(InProcessKernel, self).execute_request(stream, ident, parent) | ||
epatters
|
r8411 | |||
def start(self): | ||||
""" Override registration of dispatchers for streams. """ | ||||
self.shell.exit_now = False | ||||
def _abort_queue(self, stream): | ||||
epatters
|
r8471 | """ The in-process kernel doesn't abort requests. """ | ||
epatters
|
r8411 | pass | ||
def _raw_input(self, prompt, ident, parent): | ||||
# Flush output before making the request. | ||||
self.raw_input_str = None | ||||
sys.stderr.flush() | ||||
sys.stdout.flush() | ||||
# Send the input request. | ||||
content = json_clean(dict(prompt=prompt)) | ||||
msg = self.session.msg(u'input_request', content, parent) | ||||
for frontend in self.frontends: | ||||
if frontend.session.session == parent['header']['session']: | ||||
frontend.stdin_channel.call_handlers(msg) | ||||
break | ||||
else: | ||||
log.error('No frontend found for raw_input request') | ||||
return str() | ||||
# Await a response. | ||||
while self.raw_input_str is None: | ||||
frontend.stdin_channel.process_events() | ||||
return self.raw_input_str | ||||
#------------------------------------------------------------------------- | ||||
# Protected interface | ||||
#------------------------------------------------------------------------- | ||||
@contextmanager | ||||
def _redirected_io(self): | ||||
""" Temporarily redirect IO to the kernel. | ||||
""" | ||||
sys_stdout, sys_stderr = sys.stdout, sys.stderr | ||||
sys.stdout, sys.stderr = self.stdout, self.stderr | ||||
yield | ||||
sys.stdout, sys.stderr = sys_stdout, sys_stderr | ||||
#------ Trait change handlers -------------------------------------------- | ||||
def _io_dispatch(self): | ||||
""" Called when a message is sent to the IO socket. | ||||
""" | ||||
ident, msg = self.session.recv(self.iopub_socket, copy=False) | ||||
for frontend in self.frontends: | ||||
frontend.sub_channel.call_handlers(msg) | ||||
#------ Trait initializers ----------------------------------------------- | ||||
def _log_default(self): | ||||
return logging.getLogger(__name__) | ||||
def _session_default(self): | ||||
from IPython.zmq.session import Session | ||||
return Session(config=self.config) | ||||
def _stdout_default(self): | ||||
from IPython.zmq.iostream import OutStream | ||||
return OutStream(self.session, self.iopub_socket, u'stdout') | ||||
def _stderr_default(self): | ||||
from IPython.zmq.iostream import OutStream | ||||
return OutStream(self.session, self.iopub_socket, u'stderr') | ||||