##// 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)
@@ -2,12 +2,14 b''
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):
@@ -22,8 +24,7 b' class QtInProcessStdInChannel(QtStdInChannelMixin, InProcessStdInChannel):'
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
@@ -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,4 +1,4 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 """
@@ -12,15 +12,19 b' Useful for test suites and blocking terminal interfaces.'
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
@@ -33,7 +37,7 b' 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
@@ -41,12 +45,12 b' class BlockingInProcessStdInChannel(BlockingChannelMixin, InProcessStdInChannel)'
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)
@@ -1,4 +1,4 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
@@ -11,238 +11,49 b''
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):
@@ -268,46 +79,9 b' class InProcessKernelManager(KernelManager):'
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)
@@ -37,7 +37,8 b' class InProcessKernel(Kernel):'
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
@@ -1,7 +1,7 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.
@@ -11,177 +11,15 b''
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
@@ -191,91 +29,16 b' class InProcessKernelManager(Configurable):'
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()
@@ -289,7 +52,6 b' class InProcessKernelManager(Configurable):'
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):
@@ -306,8 +68,4 b' class InProcessKernelManager(Configurable):'
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)
@@ -16,8 +16,8 b' 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
@@ -29,33 +29,35 b' from IPython.utils import py3compat'
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?
@@ -66,21 +68,21 b' class InProcessKernelTestCase(unittest.TestCase):'
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
@@ -14,9 +14,9 b' from __future__ import print_function'
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
@@ -24,20 +24,22 b' from IPython.kernel.inprocess.ipkernel import InProcessKernel'
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)
@@ -49,37 +51,43 b' class InProcessKernelManagerTestCase(unittest.TestCase):'
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')
@@ -87,11 +95,13 b' class InProcessKernelManagerTestCase(unittest.TestCase):'
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)
General Comments 0
You need to be logged in to leave comments. Login now