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