##// END OF EJS Templates
update inprocess kernel to new layout...
MinRK -
Show More
@@ -0,0 +1,194 b''
1 """ A kernel client for in-process kernels. """
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2012 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 # IPython imports
15 from IPython.kernel.channelabc import (
16 ShellChannelABC, IOPubChannelABC,
17 HBChannelABC, StdInChannelABC,
18 )
19
20 # Local imports
21 from .socket import DummySocket
22
23 #-----------------------------------------------------------------------------
24 # Channel classes
25 #-----------------------------------------------------------------------------
26
27 class InProcessChannel(object):
28 """Base class for in-process channels."""
29 proxy_methods = []
30
31 def __init__(self, client):
32 super(InProcessChannel, self).__init__()
33 self.client = client
34 self._is_alive = False
35
36 #--------------------------------------------------------------------------
37 # Channel interface
38 #--------------------------------------------------------------------------
39
40 def is_alive(self):
41 return self._is_alive
42
43 def start(self):
44 self._is_alive = True
45
46 def stop(self):
47 self._is_alive = False
48
49 def call_handlers(self, msg):
50 """ This method is called in the main thread when a message arrives.
51
52 Subclasses should override this method to handle incoming messages.
53 """
54 raise NotImplementedError('call_handlers must be defined in a subclass.')
55
56 #--------------------------------------------------------------------------
57 # InProcessChannel interface
58 #--------------------------------------------------------------------------
59
60 def call_handlers_later(self, *args, **kwds):
61 """ Call the message handlers later.
62
63 The default implementation just calls the handlers immediately, but this
64 method exists so that GUI toolkits can defer calling the handlers until
65 after the event loop has run, as expected by GUI frontends.
66 """
67 self.call_handlers(*args, **kwds)
68
69 def process_events(self):
70 """ Process any pending GUI events.
71
72 This method will be never be called from a frontend without an event
73 loop (e.g., a terminal frontend).
74 """
75 raise NotImplementedError
76
77
78 class InProcessShellChannel(InProcessChannel):
79 """See `IPython.kernel.channels.ShellChannel` for docstrings."""
80
81 # flag for whether execute requests should be allowed to call raw_input
82 allow_stdin = True
83 proxy_methods = [
84 'execute',
85 'complete',
86 'object_info',
87 'history',
88 'shutdown',
89 ]
90
91 #--------------------------------------------------------------------------
92 # ShellChannel interface
93 #--------------------------------------------------------------------------
94
95 def execute(self, code, silent=False, store_history=True,
96 user_variables=[], user_expressions={}, allow_stdin=None):
97 if allow_stdin is None:
98 allow_stdin = self.allow_stdin
99 content = dict(code=code, silent=silent, store_history=store_history,
100 user_variables=user_variables,
101 user_expressions=user_expressions,
102 allow_stdin=allow_stdin)
103 msg = self.client.session.msg('execute_request', content)
104 self._dispatch_to_kernel(msg)
105 return msg['header']['msg_id']
106
107 def complete(self, text, line, cursor_pos, block=None):
108 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
109 msg = self.client.session.msg('complete_request', content)
110 self._dispatch_to_kernel(msg)
111 return msg['header']['msg_id']
112
113 def object_info(self, oname, detail_level=0):
114 content = dict(oname=oname, detail_level=detail_level)
115 msg = self.client.session.msg('object_info_request', content)
116 self._dispatch_to_kernel(msg)
117 return msg['header']['msg_id']
118
119 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
120 content = dict(raw=raw, output=output,
121 hist_access_type=hist_access_type, **kwds)
122 msg = self.client.session.msg('history_request', content)
123 self._dispatch_to_kernel(msg)
124 return msg['header']['msg_id']
125
126 def shutdown(self, restart=False):
127 # FIXME: What to do here?
128 raise NotImplementedError('Cannot shutdown in-process kernel')
129
130 #--------------------------------------------------------------------------
131 # Protected interface
132 #--------------------------------------------------------------------------
133
134 def _dispatch_to_kernel(self, msg):
135 """ Send a message to the kernel and handle a reply.
136 """
137 kernel = self.client.kernel
138 if kernel is None:
139 raise RuntimeError('Cannot send request. No kernel exists.')
140
141 stream = DummySocket()
142 self.client.session.send(stream, msg)
143 msg_parts = stream.recv_multipart()
144 kernel.dispatch_shell(stream, msg_parts)
145
146 idents, reply_msg = self.client.session.recv(stream, copy=False)
147 self.call_handlers_later(reply_msg)
148
149
150 class InProcessIOPubChannel(InProcessChannel):
151 """See `IPython.kernel.channels.IOPubChannel` for docstrings."""
152
153 def flush(self, timeout=1.0):
154 pass
155
156
157 class InProcessStdInChannel(InProcessChannel):
158 """See `IPython.kernel.channels.StdInChannel` for docstrings."""
159
160 proxy_methods = ['input']
161
162 def input(self, string):
163 kernel = self.client.kernel
164 if kernel is None:
165 raise RuntimeError('Cannot send input reply. No kernel exists.')
166 kernel.raw_input_str = string
167
168
169 class InProcessHBChannel(InProcessChannel):
170 """See `IPython.kernel.channels.HBChannel` for docstrings."""
171
172 time_to_dead = 3.0
173
174 def __init__(self, *args, **kwds):
175 super(InProcessHBChannel, self).__init__(*args, **kwds)
176 self._pause = True
177
178 def pause(self):
179 self._pause = True
180
181 def unpause(self):
182 self._pause = False
183
184 def is_beating(self):
185 return not self._pause
186
187 #-----------------------------------------------------------------------------
188 # ABC Registration
189 #-----------------------------------------------------------------------------
190
191 ShellChannelABC.register(InProcessShellChannel)
192 IOPubChannelABC.register(InProcessIOPubChannel)
193 HBChannelABC.register(InProcessHBChannel)
194 StdInChannelABC.register(InProcessStdInChannel)
@@ -1,33 +1,34 b''
1 1 """ Defines an in-process KernelManager with signals and slots.
2 2 """
3 3
4 4 # Local imports.
5 from IPython.kernel.inprocess.kernelmanager import \
6 InProcessShellChannel, InProcessIOPubChannel, InProcessStdInChannel, \
7 InProcessHBChannel, InProcessKernelManager
5 from IPython.kernel.inprocess import (
6 InProcessShellChannel, InProcessIOPubChannel, InProcessStdInChannel,
7 InProcessHBChannel, InProcessKernelClient
8 )
9
8 10 from IPython.utils.traitlets import Type
9 from base_kernelmanager import QtShellChannelMixin, QtIOPubChannelMixin, \
10 QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin
11 from kernel_mixins import QtShellChannelMixin, QtIOPubChannelMixin, \
12 QtStdInChannelMixin, QtHBChannelMixin, QtKernelClientMixin
11 13
12 14
13 15 class QtInProcessShellChannel(QtShellChannelMixin, InProcessShellChannel):
14 16 pass
15 17
16 18 class QtInProcessIOPubChannel(QtIOPubChannelMixin, InProcessIOPubChannel):
17 19 pass
18 20
19 21 class QtInProcessStdInChannel(QtStdInChannelMixin, InProcessStdInChannel):
20 22 pass
21 23
22 24 class QtInProcessHBChannel(QtHBChannelMixin, InProcessHBChannel):
23 25 pass
24 26
25
26 class QtInProcessKernelManager(QtKernelManagerMixin, InProcessKernelManager):
27 class QtInProcessKernelClient(QtKernelClientMixin, InProcessKernelClient):
27 28 """ An in-process KernelManager with signals and slots.
28 29 """
29 30
30 31 iopub_channel_class = Type(QtInProcessIOPubChannel)
31 32 shell_channel_class = Type(QtInProcessShellChannel)
32 33 stdin_channel_class = Type(QtInProcessStdInChannel)
33 34 hb_channel_class = Type(QtInProcessHBChannel)
@@ -0,0 +1,8 b''
1 from .channels import (
2 InProcessShellChannel,
3 InProcessIOPubChannel,
4 InProcessStdInChannel,
5 InProcessHBChannel,
6 )
7 from .client import InProcessKernelClient
8 from .manager import InProcessKernelManager No newline at end of file
@@ -1,54 +1,58 b''
1 """ Implements a fully blocking kernel manager.
1 """ Implements a fully blocking kernel client.
2 2
3 3 Useful for test suites and blocking terminal interfaces.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2012 The IPython Development Team
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING.txt, distributed as part of this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 from __future__ import print_function
16 15
17 # Local imports.
16 # IPython imports
18 17 from IPython.utils.io import raw_print
19 18 from IPython.utils.traitlets import Type
20 from kernelmanager import InProcessKernelManager, InProcessShellChannel, \
21 InProcessIOPubChannel, InProcessStdInChannel
22 from IPython.kernel.blockingkernelmanager import BlockingChannelMixin
19 from IPython.kernel.blocking.channels import BlockingChannelMixin
23 20
21 # Local imports
22 from .channels import (
23 InProcessShellChannel,
24 InProcessIOPubChannel,
25 InProcessStdInChannel,
26 )
27 from .client import InProcessKernelClient
24 28
25 29 #-----------------------------------------------------------------------------
26 30 # Blocking kernel manager
27 31 #-----------------------------------------------------------------------------
28 32
29 33 class BlockingInProcessShellChannel(BlockingChannelMixin, InProcessShellChannel):
30 34 pass
31 35
32 36 class BlockingInProcessIOPubChannel(BlockingChannelMixin, InProcessIOPubChannel):
33 37 pass
34 38
35 39 class BlockingInProcessStdInChannel(BlockingChannelMixin, InProcessStdInChannel):
36
40
37 41 def call_handlers(self, msg):
38 42 """ Overridden for the in-process channel.
39 43
40 44 This methods simply calls raw_input directly.
41 45 """
42 46 msg_type = msg['header']['msg_type']
43 47 if msg_type == 'input_request':
44 _raw_input = self.manager.kernel._sys_raw_input
48 _raw_input = self.client.kernel._sys_raw_input
45 49 prompt = msg['content']['prompt']
46 50 raw_print(prompt, end='')
47 51 self.input(_raw_input())
48 52
49 class BlockingInProcessKernelManager(InProcessKernelManager):
53 class BlockingInProcessKernelClient(InProcessKernelClient):
50 54
51 55 # The classes to use for the various channels.
52 56 shell_channel_class = Type(BlockingInProcessShellChannel)
53 57 iopub_channel_class = Type(BlockingInProcessIOPubChannel)
54 58 stdin_channel_class = Type(BlockingInProcessStdInChannel)
@@ -1,313 +1,87 b''
1 """ A kernel manager for in-process kernels. """
1 """A client for in-process kernels."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2012 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 # Local imports.
15 from IPython.config.configurable import Configurable
16 from IPython.utils.traitlets import Any, Instance, Type
17 from IPython.kernel.kernelmanagerabc import (
18 ShellChannelABC, IOPubChannelABC,
19 HBChannelABC, StdInChannelABC,
20 KernelManagerABC
21 )
22
23 from .socket import DummySocket
24
25 #-----------------------------------------------------------------------------
26 # Channel classes
27 #-----------------------------------------------------------------------------
28
29 class InProcessChannel(object):
30 """Base class for in-process channels."""
31
32 def __init__(self, manager):
33 super(InProcessChannel, self).__init__()
34 self.manager = manager
35 self._is_alive = False
36
37 #--------------------------------------------------------------------------
38 # Channel interface
39 #--------------------------------------------------------------------------
40
41 def is_alive(self):
42 return self._is_alive
43
44 def start(self):
45 self._is_alive = True
46
47 def stop(self):
48 self._is_alive = False
49
50 def call_handlers(self, msg):
51 """ This method is called in the main thread when a message arrives.
52
53 Subclasses should override this method to handle incoming messages.
54 """
55 raise NotImplementedError('call_handlers must be defined in a subclass.')
56
57 #--------------------------------------------------------------------------
58 # InProcessChannel interface
59 #--------------------------------------------------------------------------
60
61 def call_handlers_later(self, *args, **kwds):
62 """ Call the message handlers later.
63
64 The default implementation just calls the handlers immediately, but this
65 method exists so that GUI toolkits can defer calling the handlers until
66 after the event loop has run, as expected by GUI frontends.
67 """
68 self.call_handlers(*args, **kwds)
69
70 def process_events(self):
71 """ Process any pending GUI events.
72
73 This method will be never be called from a frontend without an event
74 loop (e.g., a terminal frontend).
75 """
76 raise NotImplementedError
77
78
79 class InProcessShellChannel(InProcessChannel):
80 """See `IPython.kernel.kernelmanager.ShellChannel` for docstrings."""
81
82 # flag for whether execute requests should be allowed to call raw_input
83 allow_stdin = True
84
85 #--------------------------------------------------------------------------
86 # ShellChannel interface
87 #--------------------------------------------------------------------------
88
89 def execute(self, code, silent=False, store_history=True,
90 user_variables=[], user_expressions={}, allow_stdin=None):
91 if allow_stdin is None:
92 allow_stdin = self.allow_stdin
93 content = dict(code=code, silent=silent, store_history=store_history,
94 user_variables=user_variables,
95 user_expressions=user_expressions,
96 allow_stdin=allow_stdin)
97 msg = self.manager.session.msg('execute_request', content)
98 self._dispatch_to_kernel(msg)
99 return msg['header']['msg_id']
100
101 def complete(self, text, line, cursor_pos, block=None):
102 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
103 msg = self.manager.session.msg('complete_request', content)
104 self._dispatch_to_kernel(msg)
105 return msg['header']['msg_id']
106
107 def object_info(self, oname, detail_level=0):
108 content = dict(oname=oname, detail_level=detail_level)
109 msg = self.manager.session.msg('object_info_request', content)
110 self._dispatch_to_kernel(msg)
111 return msg['header']['msg_id']
112
113 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
114 content = dict(raw=raw, output=output,
115 hist_access_type=hist_access_type, **kwds)
116 msg = self.manager.session.msg('history_request', content)
117 self._dispatch_to_kernel(msg)
118 return msg['header']['msg_id']
119
120 def shutdown(self, restart=False):
121 # FIXME: What to do here?
122 raise NotImplementedError('Cannot shutdown in-process kernel')
123
124 #--------------------------------------------------------------------------
125 # Protected interface
126 #--------------------------------------------------------------------------
14 # IPython imports
15 from IPython.utils.traitlets import Type, Instance
16 from IPython.kernel.clientabc import KernelClientABC
17 from IPython.kernel.client import KernelClient
127 18
128 def _dispatch_to_kernel(self, msg):
129 """ Send a message to the kernel and handle a reply.
130 """
131 kernel = self.manager.kernel
132 if kernel is None:
133 raise RuntimeError('Cannot send request. No kernel exists.')
134
135 stream = DummySocket()
136 self.manager.session.send(stream, msg)
137 msg_parts = stream.recv_multipart()
138 kernel.dispatch_shell(stream, msg_parts)
139
140 idents, reply_msg = self.manager.session.recv(stream, copy=False)
141 self.call_handlers_later(reply_msg)
142
143
144 class InProcessIOPubChannel(InProcessChannel):
145 """See `IPython.kernel.kernelmanager.IOPubChannel` for docstrings."""
146
147 def flush(self, timeout=1.0):
148 pass
149
150
151 class InProcessStdInChannel(InProcessChannel):
152 """See `IPython.kernel.kernelmanager.StdInChannel` for docstrings."""
153
154 def input(self, string):
155 kernel = self.manager.kernel
156 if kernel is None:
157 raise RuntimeError('Cannot send input reply. No kernel exists.')
158 kernel.raw_input_str = string
159
160
161 class InProcessHBChannel(InProcessChannel):
162 """See `IPython.kernel.kernelmanager.HBChannel` for docstrings."""
163
164 time_to_dead = 3.0
165
166 def __init__(self, *args, **kwds):
167 super(InProcessHBChannel, self).__init__(*args, **kwds)
168 self._pause = True
169
170 def pause(self):
171 self._pause = True
172
173 def unpause(self):
174 self._pause = False
175
176 def is_beating(self):
177 return not self._pause
19 # Local imports
20 from .channels import (
21 InProcessShellChannel,
22 InProcessIOPubChannel,
23 InProcessHBChannel,
24 InProcessStdInChannel,
178 25
26 )
179 27
180 28 #-----------------------------------------------------------------------------
181 # Main kernel manager class
29 # Main kernel Client class
182 30 #-----------------------------------------------------------------------------
183 31
184 class InProcessKernelManager(KernelManager):
185 """A manager for an in-process kernel.
32 class InProcessKernelClient(KernelClient):
33 """A client for an in-process kernel.
186 34
187 35 This class implements the interface of
188 `IPython.kernel.kernelmanagerabc.KernelManagerABC` and allows
36 `IPython.kernel.clientabc.KernelClientABC` and allows
189 37 (asynchronous) frontends to be used seamlessly with an in-process kernel.
190 38
191 See `IPython.kernel.kernelmanager.KernelManager` for docstrings.
39 See `IPython.kernel.client.KernelClient` for docstrings.
192 40 """
193 41
194 # The Session to use for building messages.
195 session = Instance('IPython.kernel.zmq.session.Session')
196 def _session_default(self):
197 from IPython.kernel.zmq.session import Session
198 return Session(config=self.config)
199
200 # The kernel process with which the KernelManager is communicating.
201 kernel = Instance('IPython.kernel.inprocess.ipkernel.InProcessKernel')
202
203 42 # The classes to use for the various channels.
204 43 shell_channel_class = Type(InProcessShellChannel)
205 44 iopub_channel_class = Type(InProcessIOPubChannel)
206 45 stdin_channel_class = Type(InProcessStdInChannel)
207 46 hb_channel_class = Type(InProcessHBChannel)
208 47
209 # Protected traits.
210 _shell_channel = Any
211 _iopub_channel = Any
212 _stdin_channel = Any
213 _hb_channel = Any
48 kernel = Instance('IPython.kernel.inprocess.ipkernel.Kernel')
214 49
215 50 #--------------------------------------------------------------------------
216 # Channel management methods.
51 # Channel management methods
217 52 #--------------------------------------------------------------------------
218 53
219 def start_channels(self, shell=True, iopub=True, stdin=True, hb=True):
220 if shell:
221 self.shell_channel.start()
222 if iopub:
223 self.iopub_channel.start()
224 if stdin:
225 self.stdin_channel.start()
226 self.shell_channel.allow_stdin = True
227 else:
228 self.shell_channel.allow_stdin = False
229 if hb:
230 self.hb_channel.start()
231
232 def stop_channels(self):
233 if self.shell_channel.is_alive():
234 self.shell_channel.stop()
235 if self.iopub_channel.is_alive():
236 self.iopub_channel.stop()
237 if self.stdin_channel.is_alive():
238 self.stdin_channel.stop()
239 if self.hb_channel.is_alive():
240 self.hb_channel.stop()
241
242 @property
243 def channels_running(self):
244 return (self.shell_channel.is_alive() or self.iopub_channel.is_alive() or
245 self.stdin_channel.is_alive() or self.hb_channel.is_alive())
54 def start_channels(self, *args, **kwargs):
55 super(InProcessKernelClient, self).start_channels(self)
56 self.kernel.frontends.append(self)
246 57
247 58 @property
248 59 def shell_channel(self):
249 60 if self._shell_channel is None:
250 61 self._shell_channel = self.shell_channel_class(self)
251 62 return self._shell_channel
252 63
253 64 @property
254 65 def iopub_channel(self):
255 66 if self._iopub_channel is None:
256 67 self._iopub_channel = self.iopub_channel_class(self)
257 68 return self._iopub_channel
258 69
259 70 @property
260 71 def stdin_channel(self):
261 72 if self._stdin_channel is None:
262 73 self._stdin_channel = self.stdin_channel_class(self)
263 74 return self._stdin_channel
264 75
265 76 @property
266 77 def hb_channel(self):
267 78 if self._hb_channel is None:
268 79 self._hb_channel = self.hb_channel_class(self)
269 80 return self._hb_channel
270 81
271 #--------------------------------------------------------------------------
272 # Kernel management methods:
273 #--------------------------------------------------------------------------
274
275 def start_kernel(self, **kwds):
276 from IPython.kernel.inprocess.ipkernel import InProcessKernel
277 self.kernel = InProcessKernel()
278 self.kernel.frontends.append(self)
279
280 def shutdown_kernel(self):
281 self._kill_kernel()
282
283 def restart_kernel(self, now=False, **kwds):
284 self.shutdown_kernel()
285 self.start_kernel(**kwds)
286
287 @property
288 def has_kernel(self):
289 return self.kernel is not None
290
291 def _kill_kernel(self):
292 self.kernel.frontends.remove(self)
293 self.kernel = None
294
295 def interrupt_kernel(self):
296 raise NotImplementedError("Cannot interrupt in-process kernel.")
297
298 def signal_kernel(self, signum):
299 raise NotImplementedError("Cannot signal in-process kernel.")
300
301 def is_alive(self):
302 return True
303
304 82
305 83 #-----------------------------------------------------------------------------
306 84 # ABC Registration
307 85 #-----------------------------------------------------------------------------
308 86
309 ShellChannelABC.register(InProcessShellChannel)
310 IOPubChannelABC.register(InProcessIOPubChannel)
311 HBChannelABC.register(InProcessHBChannel)
312 StdInChannelABC.register(InProcessStdInChannel)
313 KernelManagerABC.register(InProcessKernelManager)
87 KernelClientABC.register(InProcessKernelClient)
@@ -1,177 +1,178 b''
1 1 """An in-process kernel"""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2012 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # Standard library imports
15 15 from contextlib import contextmanager
16 16 import logging
17 17 import sys
18 18
19 19 # Local imports
20 20 from IPython.core.interactiveshell import InteractiveShellABC
21 21 from IPython.utils.jsonutil import json_clean
22 22 from IPython.utils.traitlets import Any, Enum, Instance, List, Type
23 23 from IPython.kernel.zmq.ipkernel import Kernel
24 24 from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
25 25
26 26 from .socket import DummySocket
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Main kernel class
30 30 #-----------------------------------------------------------------------------
31 31
32 32 class InProcessKernel(Kernel):
33 33
34 34 #-------------------------------------------------------------------------
35 35 # InProcessKernel interface
36 36 #-------------------------------------------------------------------------
37 37
38 38 # The frontends connected to this kernel.
39 39 frontends = List(
40 Instance('IPython.kernel.inprocess.kernelmanager.InProcessKernelManager'))
40 Instance('IPython.kernel.inprocess.client.InProcessKernelClient')
41 )
41 42
42 43 # The GUI environment that the kernel is running under. This need not be
43 44 # specified for the normal operation for the kernel, but is required for
44 45 # IPython's GUI support (including pylab). The default is 'inline' because
45 46 # it is safe under all GUI toolkits.
46 47 gui = Enum(('tk', 'gtk', 'wx', 'qt', 'qt4', 'inline'),
47 48 default_value='inline')
48 49
49 50 raw_input_str = Any()
50 51 stdout = Any()
51 52 stderr = Any()
52 53
53 54 #-------------------------------------------------------------------------
54 55 # Kernel interface
55 56 #-------------------------------------------------------------------------
56 57
57 58 shell_class = Type()
58 59 shell_streams = List()
59 60 control_stream = Any()
60 61 iopub_socket = Instance(DummySocket, ())
61 62 stdin_socket = Instance(DummySocket, ())
62 63
63 64 def __init__(self, **traits):
64 65 # When an InteractiveShell is instantiated by our base class, it binds
65 66 # the current values of sys.stdout and sys.stderr.
66 67 with self._redirected_io():
67 68 super(InProcessKernel, self).__init__(**traits)
68 69
69 70 self.iopub_socket.on_trait_change(self._io_dispatch, 'message_sent')
70 71 self.shell.kernel = self
71 72
72 73 def execute_request(self, stream, ident, parent):
73 74 """ Override for temporary IO redirection. """
74 75 with self._redirected_io():
75 76 super(InProcessKernel, self).execute_request(stream, ident, parent)
76 77
77 78 def start(self):
78 79 """ Override registration of dispatchers for streams. """
79 80 self.shell.exit_now = False
80 81
81 82 def _abort_queue(self, stream):
82 83 """ The in-process kernel doesn't abort requests. """
83 84 pass
84 85
85 86 def _raw_input(self, prompt, ident, parent):
86 87 # Flush output before making the request.
87 88 self.raw_input_str = None
88 89 sys.stderr.flush()
89 90 sys.stdout.flush()
90 91
91 92 # Send the input request.
92 93 content = json_clean(dict(prompt=prompt))
93 94 msg = self.session.msg(u'input_request', content, parent)
94 95 for frontend in self.frontends:
95 96 if frontend.session.session == parent['header']['session']:
96 97 frontend.stdin_channel.call_handlers(msg)
97 98 break
98 99 else:
99 100 logging.error('No frontend found for raw_input request')
100 101 return str()
101 102
102 103 # Await a response.
103 104 while self.raw_input_str is None:
104 105 frontend.stdin_channel.process_events()
105 106 return self.raw_input_str
106 107
107 108 #-------------------------------------------------------------------------
108 109 # Protected interface
109 110 #-------------------------------------------------------------------------
110 111
111 112 @contextmanager
112 113 def _redirected_io(self):
113 114 """ Temporarily redirect IO to the kernel.
114 115 """
115 116 sys_stdout, sys_stderr = sys.stdout, sys.stderr
116 117 sys.stdout, sys.stderr = self.stdout, self.stderr
117 118 yield
118 119 sys.stdout, sys.stderr = sys_stdout, sys_stderr
119 120
120 121 #------ Trait change handlers --------------------------------------------
121 122
122 123 def _io_dispatch(self):
123 124 """ Called when a message is sent to the IO socket.
124 125 """
125 126 ident, msg = self.session.recv(self.iopub_socket, copy=False)
126 127 for frontend in self.frontends:
127 128 frontend.iopub_channel.call_handlers(msg)
128 129
129 130 #------ Trait initializers -----------------------------------------------
130 131
131 132 def _log_default(self):
132 133 return logging.getLogger(__name__)
133 134
134 135 def _session_default(self):
135 136 from IPython.kernel.zmq.session import Session
136 137 return Session(config=self.config)
137 138
138 139 def _shell_class_default(self):
139 140 return InProcessInteractiveShell
140 141
141 142 def _stdout_default(self):
142 143 from IPython.kernel.zmq.iostream import OutStream
143 144 return OutStream(self.session, self.iopub_socket, u'stdout', pipe=False)
144 145
145 146 def _stderr_default(self):
146 147 from IPython.kernel.zmq.iostream import OutStream
147 148 return OutStream(self.session, self.iopub_socket, u'stderr', pipe=False)
148 149
149 150 #-----------------------------------------------------------------------------
150 151 # Interactive shell subclass
151 152 #-----------------------------------------------------------------------------
152 153
153 154 class InProcessInteractiveShell(ZMQInteractiveShell):
154 155
155 156 kernel = Instance('IPython.kernel.inprocess.ipkernel.InProcessKernel')
156 157
157 158 #-------------------------------------------------------------------------
158 159 # InteractiveShell interface
159 160 #-------------------------------------------------------------------------
160 161
161 162 def enable_gui(self, gui=None):
162 163 """ Enable GUI integration for the kernel.
163 164 """
164 165 from IPython.kernel.zmq.eventloops import enable_gui
165 166 if not gui:
166 167 gui = self.kernel.gui
167 168 enable_gui(gui, kernel=self.kernel)
168 169
169 170 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
170 171 """ Activate pylab support at runtime.
171 172 """
172 173 if not gui:
173 174 gui = self.kernel.gui
174 175 super(InProcessInteractiveShell, self).enable_pylab(gui, import_all,
175 176 welcome_message)
176 177
177 178 InteractiveShellABC.register(InProcessInteractiveShell)
@@ -1,313 +1,71 b''
1 """ A kernel manager for in-process kernels. """
1 """A kernel manager for in-process kernels."""
2 2
3 3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2012 The IPython Development Team
4 # Copyright (C) 2013 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 # Local imports.
15 from IPython.config.configurable import Configurable
16 from IPython.utils.traitlets import Any, Instance, Type
17 from IPython.kernel.kernelmanagerabc import (
18 ShellChannelABC, IOPubChannelABC,
19 HBChannelABC, StdInChannelABC,
20 KernelManagerABC
21 )
22
23 from .socket import DummySocket
24
25 #-----------------------------------------------------------------------------
26 # Channel classes
27 #-----------------------------------------------------------------------------
28
29 class InProcessChannel(object):
30 """Base class for in-process channels."""
31
32 def __init__(self, manager):
33 super(InProcessChannel, self).__init__()
34 self.manager = manager
35 self._is_alive = False
36
37 #--------------------------------------------------------------------------
38 # Channel interface
39 #--------------------------------------------------------------------------
40
41 def is_alive(self):
42 return self._is_alive
43
44 def start(self):
45 self._is_alive = True
46
47 def stop(self):
48 self._is_alive = False
49
50 def call_handlers(self, msg):
51 """ This method is called in the main thread when a message arrives.
52
53 Subclasses should override this method to handle incoming messages.
54 """
55 raise NotImplementedError('call_handlers must be defined in a subclass.')
56
57 #--------------------------------------------------------------------------
58 # InProcessChannel interface
59 #--------------------------------------------------------------------------
60
61 def call_handlers_later(self, *args, **kwds):
62 """ Call the message handlers later.
63
64 The default implementation just calls the handlers immediately, but this
65 method exists so that GUI toolkits can defer calling the handlers until
66 after the event loop has run, as expected by GUI frontends.
67 """
68 self.call_handlers(*args, **kwds)
69
70 def process_events(self):
71 """ Process any pending GUI events.
72
73 This method will be never be called from a frontend without an event
74 loop (e.g., a terminal frontend).
75 """
76 raise NotImplementedError
77
78
79 class InProcessShellChannel(InProcessChannel):
80 """See `IPython.kernel.kernelmanager.ShellChannel` for docstrings."""
81
82 # flag for whether execute requests should be allowed to call raw_input
83 allow_stdin = True
84
85 #--------------------------------------------------------------------------
86 # ShellChannel interface
87 #--------------------------------------------------------------------------
88
89 def execute(self, code, silent=False, store_history=True,
90 user_variables=[], user_expressions={}, allow_stdin=None):
91 if allow_stdin is None:
92 allow_stdin = self.allow_stdin
93 content = dict(code=code, silent=silent, store_history=store_history,
94 user_variables=user_variables,
95 user_expressions=user_expressions,
96 allow_stdin=allow_stdin)
97 msg = self.manager.session.msg('execute_request', content)
98 self._dispatch_to_kernel(msg)
99 return msg['header']['msg_id']
100
101 def complete(self, text, line, cursor_pos, block=None):
102 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
103 msg = self.manager.session.msg('complete_request', content)
104 self._dispatch_to_kernel(msg)
105 return msg['header']['msg_id']
106
107 def object_info(self, oname, detail_level=0):
108 content = dict(oname=oname, detail_level=detail_level)
109 msg = self.manager.session.msg('object_info_request', content)
110 self._dispatch_to_kernel(msg)
111 return msg['header']['msg_id']
112
113 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
114 content = dict(raw=raw, output=output,
115 hist_access_type=hist_access_type, **kwds)
116 msg = self.manager.session.msg('history_request', content)
117 self._dispatch_to_kernel(msg)
118 return msg['header']['msg_id']
119
120 def shutdown(self, restart=False):
121 # FIXME: What to do here?
122 raise NotImplementedError('Cannot shutdown in-process kernel')
123
124 #--------------------------------------------------------------------------
125 # Protected interface
126 #--------------------------------------------------------------------------
127
128 def _dispatch_to_kernel(self, msg):
129 """ Send a message to the kernel and handle a reply.
130 """
131 kernel = self.manager.kernel
132 if kernel is None:
133 raise RuntimeError('Cannot send request. No kernel exists.')
134
135 stream = DummySocket()
136 self.manager.session.send(stream, msg)
137 msg_parts = stream.recv_multipart()
138 kernel.dispatch_shell(stream, msg_parts)
139
140 idents, reply_msg = self.manager.session.recv(stream, copy=False)
141 self.call_handlers_later(reply_msg)
142
143
144 class InProcessIOPubChannel(InProcessChannel):
145 """See `IPython.kernel.kernelmanager.IOPubChannel` for docstrings."""
146
147 def flush(self, timeout=1.0):
148 pass
149
150
151 class InProcessStdInChannel(InProcessChannel):
152 """See `IPython.kernel.kernelmanager.StdInChannel` for docstrings."""
153
154 def input(self, string):
155 kernel = self.manager.kernel
156 if kernel is None:
157 raise RuntimeError('Cannot send input reply. No kernel exists.')
158 kernel.raw_input_str = string
159
160
161 class InProcessHBChannel(InProcessChannel):
162 """See `IPython.kernel.kernelmanager.HBChannel` for docstrings."""
163
164 time_to_dead = 3.0
165
166 def __init__(self, *args, **kwds):
167 super(InProcessHBChannel, self).__init__(*args, **kwds)
168 self._pause = True
169
170 def pause(self):
171 self._pause = True
172
173 def unpause(self):
174 self._pause = False
175
176 def is_beating(self):
177 return not self._pause
178
14 from IPython.utils.traitlets import Instance
15 from IPython.kernel.managerabc import KernelManagerABC
16 from IPython.kernel.manager import KernelManager
179 17
180 18 #-----------------------------------------------------------------------------
181 19 # Main kernel manager class
182 20 #-----------------------------------------------------------------------------
183 21
184 class InProcessKernelManager(Configurable):
22 class InProcessKernelManager(KernelManager):
185 23 """A manager for an in-process kernel.
186 24
187 25 This class implements the interface of
188 26 `IPython.kernel.kernelmanagerabc.KernelManagerABC` and allows
189 27 (asynchronous) frontends to be used seamlessly with an in-process kernel.
190 28
191 29 See `IPython.kernel.kernelmanager.KernelManager` for docstrings.
192 30 """
193 31
194 # The Session to use for building messages.
195 session = Instance('IPython.kernel.zmq.session.Session')
196 def _session_default(self):
197 from IPython.kernel.zmq.session import Session
198 return Session(config=self.config)
199
200 32 # The kernel process with which the KernelManager is communicating.
201 33 kernel = Instance('IPython.kernel.inprocess.ipkernel.InProcessKernel')
202 34
203 # The classes to use for the various channels.
204 shell_channel_class = Type(InProcessShellChannel)
205 iopub_channel_class = Type(InProcessIOPubChannel)
206 stdin_channel_class = Type(InProcessStdInChannel)
207 hb_channel_class = Type(InProcessHBChannel)
208
209 # Protected traits.
210 _shell_channel = Any
211 _iopub_channel = Any
212 _stdin_channel = Any
213 _hb_channel = Any
214
215 #--------------------------------------------------------------------------
216 # Channel management methods.
217 #--------------------------------------------------------------------------
218
219 def start_channels(self, shell=True, iopub=True, stdin=True, hb=True):
220 if shell:
221 self.shell_channel.start()
222 if iopub:
223 self.iopub_channel.start()
224 if stdin:
225 self.stdin_channel.start()
226 self.shell_channel.allow_stdin = True
227 else:
228 self.shell_channel.allow_stdin = False
229 if hb:
230 self.hb_channel.start()
231
232 def stop_channels(self):
233 if self.shell_channel.is_alive():
234 self.shell_channel.stop()
235 if self.iopub_channel.is_alive():
236 self.iopub_channel.stop()
237 if self.stdin_channel.is_alive():
238 self.stdin_channel.stop()
239 if self.hb_channel.is_alive():
240 self.hb_channel.stop()
241
242 @property
243 def channels_running(self):
244 return (self.shell_channel.is_alive() or self.iopub_channel.is_alive() or
245 self.stdin_channel.is_alive() or self.hb_channel.is_alive())
246
247 @property
248 def shell_channel(self):
249 if self._shell_channel is None:
250 self._shell_channel = self.shell_channel_class(self)
251 return self._shell_channel
252
253 @property
254 def iopub_channel(self):
255 if self._iopub_channel is None:
256 self._iopub_channel = self.iopub_channel_class(self)
257 return self._iopub_channel
258
259 @property
260 def stdin_channel(self):
261 if self._stdin_channel is None:
262 self._stdin_channel = self.stdin_channel_class(self)
263 return self._stdin_channel
264
265 @property
266 def hb_channel(self):
267 if self._hb_channel is None:
268 self._hb_channel = self.hb_channel_class(self)
269 return self._hb_channel
270
271 35 #--------------------------------------------------------------------------
272 # Kernel management methods:
36 # Kernel management methods
273 37 #--------------------------------------------------------------------------
274 38
275 39 def start_kernel(self, **kwds):
276 40 from IPython.kernel.inprocess.ipkernel import InProcessKernel
277 41 self.kernel = InProcessKernel()
278 self.kernel.frontends.append(self)
279 42
280 43 def shutdown_kernel(self):
281 44 self._kill_kernel()
282 45
283 46 def restart_kernel(self, now=False, **kwds):
284 47 self.shutdown_kernel()
285 48 self.start_kernel(**kwds)
286 49
287 50 @property
288 51 def has_kernel(self):
289 52 return self.kernel is not None
290 53
291 54 def _kill_kernel(self):
292 self.kernel.frontends.remove(self)
293 55 self.kernel = None
294 56
295 57 def interrupt_kernel(self):
296 58 raise NotImplementedError("Cannot interrupt in-process kernel.")
297 59
298 60 def signal_kernel(self, signum):
299 61 raise NotImplementedError("Cannot signal in-process kernel.")
300 62
301 63 def is_alive(self):
302 64 return True
303 65
304 66
305 67 #-----------------------------------------------------------------------------
306 68 # ABC Registration
307 69 #-----------------------------------------------------------------------------
308 70
309 ShellChannelABC.register(InProcessShellChannel)
310 IOPubChannelABC.register(InProcessIOPubChannel)
311 HBChannelABC.register(InProcessHBChannel)
312 StdInChannelABC.register(InProcessStdInChannel)
313 71 KernelManagerABC.register(InProcessKernelManager)
@@ -1,89 +1,91 b''
1 1 #-------------------------------------------------------------------------------
2 2 # Copyright (C) 2012 The IPython Development Team
3 3 #
4 4 # Distributed under the terms of the BSD License. The full license is in
5 5 # the file COPYING, distributed as part of this software.
6 6 #-------------------------------------------------------------------------------
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11 from __future__ import print_function
12 12
13 13 # Standard library imports
14 14 from StringIO import StringIO
15 15 import sys
16 16 import unittest
17 17
18 18 # Local imports
19 from IPython.kernel.inprocess.blockingkernelmanager import \
20 BlockingInProcessKernelManager
19 from IPython.kernel.inprocess.blocking import BlockingInProcessKernelClient
20 from IPython.kernel.inprocess.manager import InProcessKernelManager
21 21 from IPython.kernel.inprocess.ipkernel import InProcessKernel
22 22 from IPython.testing.decorators import skipif_not_matplotlib
23 23 from IPython.utils.io import capture_output
24 24 from IPython.utils import py3compat
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Test case
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class InProcessKernelTestCase(unittest.TestCase):
31 31
32 def setUp(self):
33 self.km = InProcessKernelManager()
34 self.km.start_kernel()
35 self.kc = BlockingInProcessKernelClient(kernel=self.km.kernel)
36 self.kc.start_channels()
37
32 38 @skipif_not_matplotlib
33 39 def test_pylab(self):
34 40 """ Does pylab work in the in-process kernel?
35 41 """
36 km = BlockingInProcessKernelManager()
37 km.start_kernel()
38 km.shell_channel.execute('%pylab')
39 msg = get_stream_message(km)
42 kc = self.kc
43 kc.execute('%pylab')
44 msg = get_stream_message(kc)
40 45 self.assert_('Welcome to pylab' in msg['content']['data'])
41 46
42 47 def test_raw_input(self):
43 48 """ Does the in-process kernel handle raw_input correctly?
44 49 """
45 km = BlockingInProcessKernelManager()
46 km.start_kernel()
47
48 50 io = StringIO('foobar\n')
49 51 sys_stdin = sys.stdin
50 52 sys.stdin = io
51 53 try:
52 54 if py3compat.PY3:
53 km.shell_channel.execute('x = input()')
55 self.kc.execute('x = input()')
54 56 else:
55 km.shell_channel.execute('x = raw_input()')
57 self.kc.execute('x = raw_input()')
56 58 finally:
57 59 sys.stdin = sys_stdin
58 self.assertEqual(km.kernel.shell.user_ns.get('x'), 'foobar')
60 self.assertEqual(self.km.kernel.shell.user_ns.get('x'), 'foobar')
59 61
60 62 def test_stdout(self):
61 63 """ Does the in-process kernel correctly capture IO?
62 64 """
63 65 kernel = InProcessKernel()
64 66
65 67 with capture_output() as io:
66 68 kernel.shell.run_cell('print("foo")')
67 69 self.assertEqual(io.stdout, 'foo\n')
68 70
69 km = BlockingInProcessKernelManager(kernel=kernel)
70 kernel.frontends.append(km)
71 km.shell_channel.execute('print("bar")')
72 msg = get_stream_message(km)
71 kc = BlockingInProcessKernelClient(kernel=kernel)
72 kernel.frontends.append(kc)
73 kc.shell_channel.execute('print("bar")')
74 msg = get_stream_message(kc)
73 75 self.assertEqual(msg['content']['data'], 'bar\n')
74 76
75 77 #-----------------------------------------------------------------------------
76 78 # Utility functions
77 79 #-----------------------------------------------------------------------------
78 80
79 def get_stream_message(kernel_manager, timeout=5):
81 def get_stream_message(kernel_client, timeout=5):
80 82 """ Gets a single stream message synchronously from the sub channel.
81 83 """
82 84 while True:
83 msg = kernel_manager.iopub_channel.get_msg(timeout=timeout)
85 msg = kernel_client.get_iopub_msg(timeout=timeout)
84 86 if msg['header']['msg_type'] == 'stream':
85 87 return msg
86 88
87 89
88 90 if __name__ == '__main__':
89 91 unittest.main()
@@ -1,102 +1,112 b''
1 1 #-------------------------------------------------------------------------------
2 2 # Copyright (C) 2012 The IPython Development Team
3 3 #
4 4 # Distributed under the terms of the BSD License. The full license is in
5 5 # the file COPYING, distributed as part of this software.
6 6 #-------------------------------------------------------------------------------
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11 from __future__ import print_function
12 12
13 13 # Standard library imports
14 14 import unittest
15 15
16 16 # Local imports
17 from IPython.kernel.inprocess.blockingkernelmanager import \
18 BlockingInProcessKernelManager
17 from IPython.kernel.inprocess.blocking import BlockingInProcessKernelClient
19 18 from IPython.kernel.inprocess.ipkernel import InProcessKernel
19 from IPython.kernel.inprocess.manager import InProcessKernelManager
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Test case
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class InProcessKernelManagerTestCase(unittest.TestCase):
26 26
27 def test_inteface(self):
27 def test_interface(self):
28 28 """ Does the in-process kernel manager implement the basic KM interface?
29 29 """
30 km = BlockingInProcessKernelManager()
31 self.assert_(not km.channels_running)
30 km = InProcessKernelManager()
32 31 self.assert_(not km.has_kernel)
33 32
34 km.start_channels()
35 self.assert_(km.channels_running)
36
37 33 km.start_kernel()
38 34 self.assert_(km.has_kernel)
39 35 self.assert_(km.kernel is not None)
40 36
37 kc = BlockingInProcessKernelClient(kernel=km.kernel)
38 self.assert_(not kc.channels_running)
39
40 kc.start_channels()
41 self.assert_(kc.channels_running)
42
41 43 old_kernel = km.kernel
42 44 km.restart_kernel()
43 45 self.assert_(km.kernel is not None)
44 46 self.assertNotEquals(km.kernel, old_kernel)
45 47
46 48 km.shutdown_kernel()
47 49 self.assert_(not km.has_kernel)
48 50
49 51 self.assertRaises(NotImplementedError, km.interrupt_kernel)
50 52 self.assertRaises(NotImplementedError, km.signal_kernel, 9)
51 53
52 km.stop_channels()
53 self.assert_(not km.channels_running)
54 kc.stop_channels()
55 self.assert_(not kc.channels_running)
54 56
55 57 def test_execute(self):
56 58 """ Does executing code in an in-process kernel work?
57 59 """
58 km = BlockingInProcessKernelManager()
60 km = InProcessKernelManager()
59 61 km.start_kernel()
60 km.shell_channel.execute('foo = 1')
62 kc = BlockingInProcessKernelClient(kernel=km.kernel)
63 kc.start_channels()
64 kc.execute('foo = 1')
61 65 self.assertEquals(km.kernel.shell.user_ns['foo'], 1)
62 66
63 67 def test_complete(self):
64 68 """ Does requesting completion from an in-process kernel work?
65 69 """
66 km = BlockingInProcessKernelManager()
70 km = InProcessKernelManager()
67 71 km.start_kernel()
72 kc = BlockingInProcessKernelClient(kernel=km.kernel)
73 kc.start_channels()
68 74 km.kernel.shell.push({'my_bar': 0, 'my_baz': 1})
69 km.shell_channel.complete('my_ba', 'my_ba', 5)
70 msg = km.shell_channel.get_msg()
71 self.assertEquals(msg['header']['msg_type'], 'complete_reply')
72 self.assertEquals(sorted(msg['content']['matches']),
75 kc.complete('my_ba', 'my_ba', 5)
76 msg = kc.get_shell_msg()
77 self.assertEqual(msg['header']['msg_type'], 'complete_reply')
78 self.assertEqual(sorted(msg['content']['matches']),
73 79 ['my_bar', 'my_baz'])
74 80
75 81 def test_object_info(self):
76 82 """ Does requesting object information from an in-process kernel work?
77 83 """
78 km = BlockingInProcessKernelManager()
84 km = InProcessKernelManager()
79 85 km.start_kernel()
86 kc = BlockingInProcessKernelClient(kernel=km.kernel)
87 kc.start_channels()
80 88 km.kernel.shell.user_ns['foo'] = 1
81 km.shell_channel.object_info('foo')
82 msg = km.shell_channel.get_msg()
89 kc.object_info('foo')
90 msg = kc.get_shell_msg()
83 91 self.assertEquals(msg['header']['msg_type'], 'object_info_reply')
84 92 self.assertEquals(msg['content']['name'], 'foo')
85 93 self.assertEquals(msg['content']['type_name'], 'int')
86 94
87 95 def test_history(self):
88 96 """ Does requesting history from an in-process kernel work?
89 97 """
90 km = BlockingInProcessKernelManager()
98 km = InProcessKernelManager()
91 99 km.start_kernel()
92 km.shell_channel.execute('%who')
93 km.shell_channel.history(hist_access_type='tail', n=1)
94 msg = km.shell_channel.get_msgs()[-1]
100 kc = BlockingInProcessKernelClient(kernel=km.kernel)
101 kc.start_channels()
102 kc.execute('%who')
103 kc.history(hist_access_type='tail', n=1)
104 msg = kc.shell_channel.get_msgs()[-1]
95 105 self.assertEquals(msg['header']['msg_type'], 'history_reply')
96 106 history = msg['content']['history']
97 107 self.assertEquals(len(history), 1)
98 108 self.assertEquals(history[0][2], '%who')
99 109
100 110
101 111 if __name__ == '__main__':
102 112 unittest.main()
General Comments 0
You need to be logged in to leave comments. Login now