blocking.py
94 lines
| 3.1 KiB
| text/x-python
|
PythonLexer
MinRK
|
r10298 | """ Implements a fully blocking kernel client. | ||
epatters
|
r8408 | |||
Useful for test suites and blocking terminal interfaces. | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (C) 2012 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. | ||||
#----------------------------------------------------------------------------- | ||||
Thomas Kluyver
|
r19208 | try: | ||
from queue import Queue, Empty # Py 3 | ||||
except ImportError: | ||||
from Queue import Queue, Empty # Py 2 | ||||
epatters
|
r8408 | |||
MinRK
|
r10298 | # IPython imports | ||
epatters
|
r8482 | from IPython.utils.io import raw_print | ||
epatters
|
r8408 | from IPython.utils.traitlets import Type | ||
Thomas Kluyver
|
r19208 | #from IPython.kernel.blocking.channels import BlockingChannelMixin | ||
epatters
|
r8408 | |||
MinRK
|
r10298 | # Local imports | ||
from .channels import ( | ||||
Thomas Kluyver
|
r19223 | InProcessChannel, | ||
MinRK
|
r10298 | ) | ||
from .client import InProcessKernelClient | ||||
epatters
|
r8408 | |||
Thomas Kluyver
|
r19223 | class BlockingInProcessChannel(InProcessChannel): | ||
Thomas Kluyver
|
r19208 | |||
def __init__(self, *args, **kwds): | ||||
Thomas Kluyver
|
r19223 | super(BlockingInProcessChannel, self).__init__(*args, **kwds) | ||
Thomas Kluyver
|
r19208 | self._in_queue = Queue() | ||
def call_handlers(self, msg): | ||||
self._in_queue.put(msg) | ||||
def get_msg(self, block=True, timeout=None): | ||||
""" Gets a message if there is one that is ready. """ | ||||
if timeout is None: | ||||
# Queue.get(timeout=None) has stupid uninteruptible | ||||
# behavior, so wait for a week instead | ||||
timeout = 604800 | ||||
return self._in_queue.get(block, timeout) | ||||
def get_msgs(self): | ||||
""" Get all messages that are currently ready. """ | ||||
msgs = [] | ||||
while True: | ||||
try: | ||||
msgs.append(self.get_msg(block=False)) | ||||
except Empty: | ||||
break | ||||
return msgs | ||||
def msg_ready(self): | ||||
""" Is there a message that has been received? """ | ||||
return not self._in_queue.empty() | ||||
epatters
|
r8408 | |||
MinRK
|
r10298 | |||
Thomas Kluyver
|
r19223 | class BlockingInProcessStdInChannel(BlockingInProcessChannel): | ||
epatters
|
r8482 | def call_handlers(self, msg): | ||
""" Overridden for the in-process channel. | ||||
This methods simply calls raw_input directly. | ||||
""" | ||||
msg_type = msg['header']['msg_type'] | ||||
if msg_type == 'input_request': | ||||
MinRK
|
r10298 | _raw_input = self.client.kernel._sys_raw_input | ||
epatters
|
r8482 | prompt = msg['content']['prompt'] | ||
raw_print(prompt, end='') | ||||
Thomas Kluyver
|
r19223 | self.client.input(_raw_input()) | ||
epatters
|
r8408 | |||
MinRK
|
r10298 | class BlockingInProcessKernelClient(InProcessKernelClient): | ||
epatters
|
r8408 | |||
# The classes to use for the various channels. | ||||
Thomas Kluyver
|
r19223 | shell_channel_class = Type(BlockingInProcessChannel) | ||
iopub_channel_class = Type(BlockingInProcessChannel) | ||||
Brian Granger
|
r9120 | stdin_channel_class = Type(BlockingInProcessStdInChannel) | ||
Thomas Kluyver
|
r19223 | |||
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 | ||||