Show More
@@ -1,453 +1,313 b'' | |||
|
1 | 1 | """ A kernel manager for in-process kernels. """ |
|
2 | 2 | |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | # Copyright (C) 2012 The IPython Development Team |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the BSD License. The full license is in |
|
7 | 7 | # the file COPYING, distributed as part of this software. |
|
8 | 8 | #----------------------------------------------------------------------------- |
|
9 | 9 | |
|
10 | 10 | #----------------------------------------------------------------------------- |
|
11 | 11 | # Imports |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | |
|
14 | 14 | # Local imports. |
|
15 | 15 | from IPython.config.configurable import Configurable |
|
16 | 16 | from IPython.inprocess.socket import DummySocket |
|
17 | 17 | from IPython.utils.traitlets import Any, Instance, Type |
|
18 | 18 | from IPython.zmq.kernelmanagerabc import ( |
|
19 | 19 | ShellChannelABC, IOPubChannelABC, |
|
20 | 20 | HBChannelABC, StdInChannelABC, |
|
21 | 21 | KernelManagerABC |
|
22 | 22 | ) |
|
23 | 23 | |
|
24 | 24 | #----------------------------------------------------------------------------- |
|
25 | 25 | # Channel classes |
|
26 | 26 | #----------------------------------------------------------------------------- |
|
27 | 27 | |
|
28 | 28 | class InProcessChannel(object): |
|
29 |
""" |
|
|
30 | """ | |
|
29 | """Base class for in-process channels.""" | |
|
31 | 30 | |
|
32 | 31 | def __init__(self, manager): |
|
33 | 32 | super(InProcessChannel, self).__init__() |
|
34 | 33 | self.manager = manager |
|
35 | 34 | self._is_alive = False |
|
36 | 35 | |
|
37 | 36 | #-------------------------------------------------------------------------- |
|
38 | 37 | # Channel interface |
|
39 | 38 | #-------------------------------------------------------------------------- |
|
40 | 39 | |
|
41 | 40 | def is_alive(self): |
|
42 | 41 | return self._is_alive |
|
43 | 42 | |
|
44 | 43 | def start(self): |
|
45 | 44 | self._is_alive = True |
|
46 | 45 | |
|
47 | 46 | def stop(self): |
|
48 | 47 | self._is_alive = False |
|
49 | 48 | |
|
50 | 49 | def call_handlers(self, msg): |
|
51 | 50 | """ This method is called in the main thread when a message arrives. |
|
52 | 51 | |
|
53 | 52 | Subclasses should override this method to handle incoming messages. |
|
54 | 53 | """ |
|
55 | 54 | raise NotImplementedError('call_handlers must be defined in a subclass.') |
|
56 | 55 | |
|
57 | 56 | #-------------------------------------------------------------------------- |
|
58 | 57 | # InProcessChannel interface |
|
59 | 58 | #-------------------------------------------------------------------------- |
|
60 | 59 | |
|
61 | 60 | def call_handlers_later(self, *args, **kwds): |
|
62 | 61 | """ Call the message handlers later. |
|
63 | 62 | |
|
64 | 63 | The default implementation just calls the handlers immediately, but this |
|
65 | 64 | method exists so that GUI toolkits can defer calling the handlers until |
|
66 | 65 | after the event loop has run, as expected by GUI frontends. |
|
67 | 66 | """ |
|
68 | 67 | self.call_handlers(*args, **kwds) |
|
69 | 68 | |
|
70 | 69 | def process_events(self): |
|
71 | 70 | """ Process any pending GUI events. |
|
72 | 71 | |
|
73 | 72 | This method will be never be called from a frontend without an event |
|
74 | 73 | loop (e.g., a terminal frontend). |
|
75 | 74 | """ |
|
76 | 75 | raise NotImplementedError |
|
77 | 76 | |
|
78 | 77 | |
|
79 | 78 | class InProcessShellChannel(InProcessChannel): |
|
80 | """The DEALER channel for issues request/replies to the kernel. | |
|
81 | """ | |
|
79 | """See `IPython.zmq.kernelmanager.ShellChannel` for docstrings.""" | |
|
82 | 80 | |
|
83 | 81 | # flag for whether execute requests should be allowed to call raw_input |
|
84 | 82 | allow_stdin = True |
|
85 | 83 | |
|
86 | 84 | #-------------------------------------------------------------------------- |
|
87 | 85 | # ShellChannel interface |
|
88 | 86 | #-------------------------------------------------------------------------- |
|
89 | 87 | |
|
90 | 88 | def execute(self, code, silent=False, store_history=True, |
|
91 | 89 | user_variables=[], user_expressions={}, allow_stdin=None): |
|
92 | """Execute code in the kernel. | |
|
93 | ||
|
94 | Parameters | |
|
95 | ---------- | |
|
96 | code : str | |
|
97 | A string of Python code. | |
|
98 | ||
|
99 | silent : bool, optional (default False) | |
|
100 | If set, the kernel will execute the code as quietly possible, and | |
|
101 | will force store_history to be False. | |
|
102 | ||
|
103 | store_history : bool, optional (default True) | |
|
104 | If set, the kernel will store command history. This is forced | |
|
105 | to be False if silent is True. | |
|
106 | ||
|
107 | user_variables : list, optional | |
|
108 | A list of variable names to pull from the user's namespace. They | |
|
109 | will come back as a dict with these names as keys and their | |
|
110 | :func:`repr` as values. | |
|
111 | ||
|
112 | user_expressions : dict, optional | |
|
113 | A dict mapping names to expressions to be evaluated in the user's | |
|
114 | dict. The expression values are returned as strings formatted using | |
|
115 | :func:`repr`. | |
|
116 | ||
|
117 | allow_stdin : bool, optional (default self.allow_stdin) | |
|
118 | Flag for whether the kernel can send stdin requests to frontends. | |
|
119 | ||
|
120 | Some frontends (e.g. the Notebook) do not support stdin requests. | |
|
121 | If raw_input is called from code executed from such a frontend, a | |
|
122 | StdinNotImplementedError will be raised. | |
|
123 | ||
|
124 | Returns | |
|
125 | ------- | |
|
126 | The msg_id of the message sent. | |
|
127 | """ | |
|
128 | 90 | if allow_stdin is None: |
|
129 | 91 | allow_stdin = self.allow_stdin |
|
130 | 92 | content = dict(code=code, silent=silent, store_history=store_history, |
|
131 | 93 | user_variables=user_variables, |
|
132 | 94 | user_expressions=user_expressions, |
|
133 | 95 | allow_stdin=allow_stdin) |
|
134 | 96 | msg = self.manager.session.msg('execute_request', content) |
|
135 | 97 | self._dispatch_to_kernel(msg) |
|
136 | 98 | return msg['header']['msg_id'] |
|
137 | 99 | |
|
138 | 100 | def complete(self, text, line, cursor_pos, block=None): |
|
139 | """Tab complete text in the kernel's namespace. | |
|
140 | ||
|
141 | Parameters | |
|
142 | ---------- | |
|
143 | text : str | |
|
144 | The text to complete. | |
|
145 | line : str | |
|
146 | The full line of text that is the surrounding context for the | |
|
147 | text to complete. | |
|
148 | cursor_pos : int | |
|
149 | The position of the cursor in the line where the completion was | |
|
150 | requested. | |
|
151 | block : str, optional | |
|
152 | The full block of code in which the completion is being requested. | |
|
153 | ||
|
154 | Returns | |
|
155 | ------- | |
|
156 | The msg_id of the message sent. | |
|
157 | """ | |
|
158 | 101 | content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos) |
|
159 | 102 | msg = self.manager.session.msg('complete_request', content) |
|
160 | 103 | self._dispatch_to_kernel(msg) |
|
161 | 104 | return msg['header']['msg_id'] |
|
162 | 105 | |
|
163 | 106 | def object_info(self, oname, detail_level=0): |
|
164 | """Get metadata information about an object. | |
|
165 | ||
|
166 | Parameters | |
|
167 | ---------- | |
|
168 | oname : str | |
|
169 | A string specifying the object name. | |
|
170 | detail_level : int, optional | |
|
171 | The level of detail for the introspection (0-2) | |
|
172 | ||
|
173 | Returns | |
|
174 | ------- | |
|
175 | The msg_id of the message sent. | |
|
176 | """ | |
|
177 | 107 | content = dict(oname=oname, detail_level=detail_level) |
|
178 | 108 | msg = self.manager.session.msg('object_info_request', content) |
|
179 | 109 | self._dispatch_to_kernel(msg) |
|
180 | 110 | return msg['header']['msg_id'] |
|
181 | 111 | |
|
182 | 112 | def history(self, raw=True, output=False, hist_access_type='range', **kwds): |
|
183 | """Get entries from the history list. | |
|
184 | ||
|
185 | Parameters | |
|
186 | ---------- | |
|
187 | raw : bool | |
|
188 | If True, return the raw input. | |
|
189 | output : bool | |
|
190 | If True, then return the output as well. | |
|
191 | hist_access_type : str | |
|
192 | 'range' (fill in session, start and stop params), 'tail' (fill in n) | |
|
193 | or 'search' (fill in pattern param). | |
|
194 | ||
|
195 | session : int | |
|
196 | For a range request, the session from which to get lines. Session | |
|
197 | numbers are positive integers; negative ones count back from the | |
|
198 | current session. | |
|
199 | start : int | |
|
200 | The first line number of a history range. | |
|
201 | stop : int | |
|
202 | The final (excluded) line number of a history range. | |
|
203 | ||
|
204 | n : int | |
|
205 | The number of lines of history to get for a tail request. | |
|
206 | ||
|
207 | pattern : str | |
|
208 | The glob-syntax pattern for a search request. | |
|
209 | ||
|
210 | Returns | |
|
211 | ------- | |
|
212 | The msg_id of the message sent. | |
|
213 | """ | |
|
214 | 113 | content = dict(raw=raw, output=output, |
|
215 | 114 | hist_access_type=hist_access_type, **kwds) |
|
216 | 115 | msg = self.manager.session.msg('history_request', content) |
|
217 | 116 | self._dispatch_to_kernel(msg) |
|
218 | 117 | return msg['header']['msg_id'] |
|
219 | 118 | |
|
220 | 119 | def shutdown(self, restart=False): |
|
221 | """ Request an immediate kernel shutdown. | |
|
222 | ||
|
223 | A dummy method for the in-process kernel. | |
|
224 | """ | |
|
225 | 120 | # FIXME: What to do here? |
|
226 | 121 | raise NotImplementedError('Cannot shutdown in-process kernel') |
|
227 | 122 | |
|
228 | 123 | #-------------------------------------------------------------------------- |
|
229 | 124 | # Protected interface |
|
230 | 125 | #-------------------------------------------------------------------------- |
|
231 | 126 | |
|
232 | 127 | def _dispatch_to_kernel(self, msg): |
|
233 | 128 | """ Send a message to the kernel and handle a reply. |
|
234 | 129 | """ |
|
235 | 130 | kernel = self.manager.kernel |
|
236 | 131 | if kernel is None: |
|
237 | 132 | raise RuntimeError('Cannot send request. No kernel exists.') |
|
238 | 133 | |
|
239 | 134 | stream = DummySocket() |
|
240 | 135 | self.manager.session.send(stream, msg) |
|
241 | 136 | msg_parts = stream.recv_multipart() |
|
242 | 137 | kernel.dispatch_shell(stream, msg_parts) |
|
243 | 138 | |
|
244 | 139 | idents, reply_msg = self.manager.session.recv(stream, copy=False) |
|
245 | 140 | self.call_handlers_later(reply_msg) |
|
246 | 141 | |
|
247 | 142 | |
|
248 | 143 | class InProcessIOPubChannel(InProcessChannel): |
|
249 | """The SUB channel which listens for messages that the kernel publishes. | |
|
250 | """ | |
|
144 | """See `IPython.zmq.kernelmanager.IOPubChannel` for docstrings.""" | |
|
251 | 145 | |
|
252 | 146 | def flush(self, timeout=1.0): |
|
253 | """ Immediately processes all pending messages on the SUB channel. | |
|
254 | ||
|
255 | A dummy method for the in-process kernel. | |
|
256 | """ | |
|
257 | 147 | pass |
|
258 | 148 | |
|
259 | 149 | |
|
260 | 150 | class InProcessStdInChannel(InProcessChannel): |
|
261 | """ A reply channel to handle raw_input requests that the kernel makes. """ | |
|
151 | """See `IPython.zmq.kernelmanager.StdInChannel` for docstrings.""" | |
|
262 | 152 | |
|
263 | 153 | def input(self, string): |
|
264 | """ Send a string of raw input to the kernel. | |
|
265 | """ | |
|
266 | 154 | kernel = self.manager.kernel |
|
267 | 155 | if kernel is None: |
|
268 | 156 | raise RuntimeError('Cannot send input reply. No kernel exists.') |
|
269 | 157 | kernel.raw_input_str = string |
|
270 | 158 | |
|
271 | 159 | |
|
272 | 160 | class InProcessHBChannel(InProcessChannel): |
|
273 | """ A dummy heartbeat channel. """ | |
|
161 | """See `IPython.zmq.kernelmanager.HBChannel` for docstrings.""" | |
|
274 | 162 | |
|
275 | 163 | time_to_dead = 3.0 |
|
276 | 164 | |
|
277 | 165 | def __init__(self, *args, **kwds): |
|
278 | 166 | super(InProcessHBChannel, self).__init__(*args, **kwds) |
|
279 | 167 | self._pause = True |
|
280 | 168 | |
|
281 | 169 | def pause(self): |
|
282 | """ Pause the heartbeat. """ | |
|
283 | 170 | self._pause = True |
|
284 | 171 | |
|
285 | 172 | def unpause(self): |
|
286 | """ Unpause the heartbeat. """ | |
|
287 | 173 | self._pause = False |
|
288 | 174 | |
|
289 | 175 | def is_beating(self): |
|
290 | """ Is the heartbeat running and responsive (and not paused). """ | |
|
291 | 176 | return not self._pause |
|
292 | 177 | |
|
293 | 178 | |
|
294 | 179 | #----------------------------------------------------------------------------- |
|
295 | 180 | # Main kernel manager class |
|
296 | 181 | #----------------------------------------------------------------------------- |
|
297 | 182 | |
|
298 | 183 | class InProcessKernelManager(Configurable): |
|
299 | 184 |
""" |
|
300 | 185 | |
|
301 |
This class implements |
|
|
302 |
` |
|
|
303 | frontends to be used seamlessly with an in-process kernel. | |
|
186 | This class implements the interface of | |
|
187 | `IPython.zmq.kernelmanagerabc.KernelManagerABC` and allows | |
|
188 | (asynchronous) frontends to be used seamlessly with an in-process kernel. | |
|
189 | ||
|
190 | See `IPython.zmq.kernelmanager.KernelManager` for docstrings. | |
|
304 | 191 | """ |
|
305 | 192 | |
|
306 | 193 | # The Session to use for building messages. |
|
307 | 194 | session = Instance('IPython.zmq.session.Session') |
|
308 | 195 | def _session_default(self): |
|
309 | 196 | from IPython.zmq.session import Session |
|
310 | 197 | return Session(config=self.config) |
|
311 | 198 | |
|
312 | 199 | # The kernel process with which the KernelManager is communicating. |
|
313 | 200 | kernel = Instance('IPython.inprocess.ipkernel.InProcessKernel') |
|
314 | 201 | |
|
315 | 202 | # The classes to use for the various channels. |
|
316 | 203 | shell_channel_class = Type(InProcessShellChannel) |
|
317 | 204 | iopub_channel_class = Type(InProcessIOPubChannel) |
|
318 | 205 | stdin_channel_class = Type(InProcessStdInChannel) |
|
319 | 206 | hb_channel_class = Type(InProcessHBChannel) |
|
320 | 207 | |
|
321 | 208 | # Protected traits. |
|
322 | 209 | _shell_channel = Any |
|
323 | 210 | _iopub_channel = Any |
|
324 | 211 | _stdin_channel = Any |
|
325 | 212 | _hb_channel = Any |
|
326 | 213 | |
|
327 | 214 | #-------------------------------------------------------------------------- |
|
328 | 215 | # Channel management methods. |
|
329 | 216 | #-------------------------------------------------------------------------- |
|
330 | 217 | |
|
331 | 218 | def start_channels(self, shell=True, iopub=True, stdin=True, hb=True): |
|
332 | """ Starts the channels for this kernel. | |
|
333 | """ | |
|
334 | 219 | if shell: |
|
335 | 220 | self.shell_channel.start() |
|
336 | 221 | if iopub: |
|
337 | 222 | self.iopub_channel.start() |
|
338 | 223 | if stdin: |
|
339 | 224 | self.stdin_channel.start() |
|
340 | 225 | self.shell_channel.allow_stdin = True |
|
341 | 226 | else: |
|
342 | 227 | self.shell_channel.allow_stdin = False |
|
343 | 228 | if hb: |
|
344 | 229 | self.hb_channel.start() |
|
345 | 230 | |
|
346 | 231 | def stop_channels(self): |
|
347 | """ Stops all the running channels for this kernel. | |
|
348 | """ | |
|
349 | 232 | if self.shell_channel.is_alive(): |
|
350 | 233 | self.shell_channel.stop() |
|
351 | 234 | if self.iopub_channel.is_alive(): |
|
352 | 235 | self.iopub_channel.stop() |
|
353 | 236 | if self.stdin_channel.is_alive(): |
|
354 | 237 | self.stdin_channel.stop() |
|
355 | 238 | if self.hb_channel.is_alive(): |
|
356 | 239 | self.hb_channel.stop() |
|
357 | 240 | |
|
358 | 241 | @property |
|
359 | 242 | def channels_running(self): |
|
360 | """ Are any of the channels created and running? """ | |
|
361 | 243 | return (self.shell_channel.is_alive() or self.iopub_channel.is_alive() or |
|
362 | 244 | self.stdin_channel.is_alive() or self.hb_channel.is_alive()) |
|
363 | 245 | |
|
364 | 246 | @property |
|
365 | 247 | def shell_channel(self): |
|
366 | """Get the REQ socket channel object to make requests of the kernel.""" | |
|
367 | 248 | if self._shell_channel is None: |
|
368 | 249 | self._shell_channel = self.shell_channel_class(self) |
|
369 | 250 | return self._shell_channel |
|
370 | 251 | |
|
371 | 252 | @property |
|
372 | 253 | def iopub_channel(self): |
|
373 | """Get the SUB socket channel object.""" | |
|
374 | 254 | if self._iopub_channel is None: |
|
375 | 255 | self._iopub_channel = self.iopub_channel_class(self) |
|
376 | 256 | return self._iopub_channel |
|
377 | 257 | |
|
378 | 258 | @property |
|
379 | 259 | def stdin_channel(self): |
|
380 | """Get the REP socket channel object to handle stdin (raw_input).""" | |
|
381 | 260 | if self._stdin_channel is None: |
|
382 | 261 | self._stdin_channel = self.stdin_channel_class(self) |
|
383 | 262 | return self._stdin_channel |
|
384 | 263 | |
|
385 | 264 | @property |
|
386 | 265 | def hb_channel(self): |
|
387 | """Get the heartbeat socket channel object to check that the | |
|
388 | kernel is alive.""" | |
|
389 | 266 | if self._hb_channel is None: |
|
390 | 267 | self._hb_channel = self.hb_channel_class(self) |
|
391 | 268 | return self._hb_channel |
|
392 | 269 | |
|
393 | 270 | #-------------------------------------------------------------------------- |
|
394 | 271 | # Kernel management methods: |
|
395 | 272 | #-------------------------------------------------------------------------- |
|
396 | 273 | |
|
397 | 274 | def start_kernel(self, **kwds): |
|
398 | """ Starts a kernel process and configures the manager to use it. | |
|
399 | """ | |
|
400 | 275 | from IPython.inprocess.ipkernel import InProcessKernel |
|
401 | 276 | self.kernel = InProcessKernel() |
|
402 | 277 | self.kernel.frontends.append(self) |
|
403 | 278 | |
|
404 | 279 | def shutdown_kernel(self): |
|
405 | """ Attempts to the stop the kernel process cleanly. If the kernel | |
|
406 | cannot be stopped and the kernel is local, it is killed. | |
|
407 | """ | |
|
408 | 280 | self.kill_kernel() |
|
409 | 281 | |
|
410 | 282 | def restart_kernel(self, now=False, **kwds): |
|
411 | """ Restarts a kernel with the arguments that were used to launch it. | |
|
412 | ||
|
413 | The 'now' parameter is ignored. | |
|
414 | """ | |
|
415 | 283 | self.shutdown_kernel() |
|
416 | 284 | self.start_kernel(**kwds) |
|
417 | 285 | |
|
418 | 286 | @property |
|
419 | 287 | def has_kernel(self): |
|
420 | """ Returns whether a kernel process has been specified for the kernel | |
|
421 | manager. | |
|
422 | """ | |
|
423 | 288 | return self.kernel is not None |
|
424 | 289 | |
|
425 | 290 | def kill_kernel(self): |
|
426 | """ Kill the running kernel. | |
|
427 | """ | |
|
428 | 291 | self.kernel.frontends.remove(self) |
|
429 | 292 | self.kernel = None |
|
430 | 293 | |
|
431 | 294 | def interrupt_kernel(self): |
|
432 | """ Interrupts the kernel. """ | |
|
433 | 295 | raise NotImplementedError("Cannot interrupt in-process kernel.") |
|
434 | 296 | |
|
435 | 297 | def signal_kernel(self, signum): |
|
436 | """ Sends a signal to the kernel. """ | |
|
437 | 298 | raise NotImplementedError("Cannot signal in-process kernel.") |
|
438 | 299 | |
|
439 | 300 | @property |
|
440 | 301 | def is_alive(self): |
|
441 | """ Is the kernel process still running? """ | |
|
442 | 302 | return True |
|
443 | 303 | |
|
444 | 304 | |
|
445 | 305 | #----------------------------------------------------------------------------- |
|
446 | 306 | # ABC Registration |
|
447 | 307 | #----------------------------------------------------------------------------- |
|
448 | 308 | |
|
449 | 309 | ShellChannelABC.register(InProcessShellChannel) |
|
450 | 310 | IOPubChannelABC.register(InProcessIOPubChannel) |
|
451 | 311 | HBChannelABC.register(InProcessHBChannel) |
|
452 | 312 | StdInChannelABC.register(InProcessStdInChannel) |
|
453 | 313 | KernelManagerABC.register(InProcessKernelManager) |
@@ -1,401 +1,229 b'' | |||
|
1 | 1 | """Abstract base classes for kernel manager and channels.""" |
|
2 | 2 | |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | # Copyright (C) 2013 The IPython Development Team |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the BSD License. The full license is in |
|
7 | 7 | # the file COPYING, distributed as part of this software. |
|
8 | 8 | #----------------------------------------------------------------------------- |
|
9 | 9 | |
|
10 | 10 | #----------------------------------------------------------------------------- |
|
11 | 11 | # Imports |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | |
|
14 | 14 | # Standard library imports. |
|
15 | 15 | import abc |
|
16 | 16 | |
|
17 | 17 | #----------------------------------------------------------------------------- |
|
18 | 18 | # Channels |
|
19 | 19 | #----------------------------------------------------------------------------- |
|
20 | 20 | |
|
21 | 21 | |
|
22 | 22 | class ChannelABC(object): |
|
23 | 23 | """A base class for all channel ABCs.""" |
|
24 | 24 | |
|
25 | 25 | __metaclass__ = abc.ABCMeta |
|
26 | 26 | |
|
27 | 27 | @abc.abstractmethod |
|
28 | 28 | def start(self): |
|
29 | 29 | pass |
|
30 | 30 | |
|
31 | 31 | @abc.abstractmethod |
|
32 | 32 | def stop(self): |
|
33 | 33 | pass |
|
34 | 34 | |
|
35 | 35 | @abc.abstractmethod |
|
36 | 36 | def is_alive(self): |
|
37 | 37 | pass |
|
38 | 38 | |
|
39 | 39 | |
|
40 | 40 | class ShellChannelABC(ChannelABC): |
|
41 | """The DEALER channel for issues request/replies to the kernel. | |
|
41 | """ShellChannel ABC. | |
|
42 | ||
|
43 | The docstrings for this class can be found in the base implementation: | |
|
44 | ||
|
45 | `IPython.zmq.kernelmanager.ShellChannel` | |
|
42 | 46 | """ |
|
43 | 47 | |
|
44 | 48 | @abc.abstractproperty |
|
45 | 49 | def allow_stdin(self): |
|
46 | 50 | pass |
|
47 | 51 | |
|
48 | 52 | @abc.abstractmethod |
|
49 | 53 | def execute(self, code, silent=False, store_history=True, |
|
50 | 54 | user_variables=None, user_expressions=None, allow_stdin=None): |
|
51 | """Execute code in the kernel. | |
|
52 | ||
|
53 | Parameters | |
|
54 | ---------- | |
|
55 | code : str | |
|
56 | A string of Python code. | |
|
57 | ||
|
58 | silent : bool, optional (default False) | |
|
59 | If set, the kernel will execute the code as quietly possible, and | |
|
60 | will force store_history to be False. | |
|
61 | ||
|
62 | store_history : bool, optional (default True) | |
|
63 | If set, the kernel will store command history. This is forced | |
|
64 | to be False if silent is True. | |
|
65 | ||
|
66 | user_variables : list, optional | |
|
67 | A list of variable names to pull from the user's namespace. They | |
|
68 | will come back as a dict with these names as keys and their | |
|
69 | :func:`repr` as values. | |
|
70 | ||
|
71 | user_expressions : dict, optional | |
|
72 | A dict mapping names to expressions to be evaluated in the user's | |
|
73 | dict. The expression values are returned as strings formatted using | |
|
74 | :func:`repr`. | |
|
75 | ||
|
76 | allow_stdin : bool, optional (default self.allow_stdin) | |
|
77 | Flag for whether the kernel can send stdin requests to frontends. | |
|
78 | ||
|
79 | Some frontends (e.g. the Notebook) do not support stdin requests. | |
|
80 | If raw_input is called from code executed from such a frontend, a | |
|
81 | StdinNotImplementedError will be raised. | |
|
82 | ||
|
83 | Returns | |
|
84 | ------- | |
|
85 | The msg_id of the message sent. | |
|
86 | """ | |
|
87 | 55 | pass |
|
88 | 56 | |
|
89 | 57 | @abc.abstractmethod |
|
90 | 58 | def complete(self, text, line, cursor_pos, block=None): |
|
91 | """Tab complete text in the kernel's namespace. | |
|
92 | ||
|
93 | Parameters | |
|
94 | ---------- | |
|
95 | text : str | |
|
96 | The text to complete. | |
|
97 | line : str | |
|
98 | The full line of text that is the surrounding context for the | |
|
99 | text to complete. | |
|
100 | cursor_pos : int | |
|
101 | The position of the cursor in the line where the completion was | |
|
102 | requested. | |
|
103 | block : str, optional | |
|
104 | The full block of code in which the completion is being requested. | |
|
105 | ||
|
106 | Returns | |
|
107 | ------- | |
|
108 | The msg_id of the message sent. | |
|
109 | """ | |
|
110 | 59 | pass |
|
111 | 60 | |
|
112 | 61 | @abc.abstractmethod |
|
113 | 62 | def object_info(self, oname, detail_level=0): |
|
114 | """Get metadata information about an object. | |
|
115 | ||
|
116 | Parameters | |
|
117 | ---------- | |
|
118 | oname : str | |
|
119 | A string specifying the object name. | |
|
120 | detail_level : int, optional | |
|
121 | The level of detail for the introspection (0-2) | |
|
122 | ||
|
123 | Returns | |
|
124 | ------- | |
|
125 | The msg_id of the message sent. | |
|
126 | """ | |
|
127 | 63 | pass |
|
128 | 64 | |
|
129 | 65 | @abc.abstractmethod |
|
130 | 66 | def history(self, raw=True, output=False, hist_access_type='range', **kwargs): |
|
131 | """Get entries from the history list. | |
|
132 | ||
|
133 | Parameters | |
|
134 | ---------- | |
|
135 | raw : bool | |
|
136 | If True, return the raw input. | |
|
137 | output : bool | |
|
138 | If True, then return the output as well. | |
|
139 | hist_access_type : str | |
|
140 | 'range' (fill in session, start and stop params), 'tail' (fill in n) | |
|
141 | or 'search' (fill in pattern param). | |
|
142 | ||
|
143 | session : int | |
|
144 | For a range request, the session from which to get lines. Session | |
|
145 | numbers are positive integers; negative ones count back from the | |
|
146 | current session. | |
|
147 | start : int | |
|
148 | The first line number of a history range. | |
|
149 | stop : int | |
|
150 | The final (excluded) line number of a history range. | |
|
151 | ||
|
152 | n : int | |
|
153 | The number of lines of history to get for a tail request. | |
|
154 | ||
|
155 | pattern : str | |
|
156 | The glob-syntax pattern for a search request. | |
|
157 | ||
|
158 | Returns | |
|
159 | ------- | |
|
160 | The msg_id of the message sent. | |
|
161 | """ | |
|
162 | 67 | pass |
|
163 | 68 | |
|
164 | 69 | @abc.abstractmethod |
|
165 | 70 | def kernel_info(self): |
|
166 | """Request kernel info.""" | |
|
167 | 71 | pass |
|
168 | 72 | |
|
169 | 73 | @abc.abstractmethod |
|
170 | 74 | def shutdown(self, restart=False): |
|
171 | """Request an immediate kernel shutdown. | |
|
172 | ||
|
173 | Upon receipt of the (empty) reply, client code can safely assume that | |
|
174 | the kernel has shut down and it's safe to forcefully terminate it if | |
|
175 | it's still alive. | |
|
176 | ||
|
177 | The kernel will send the reply via a function registered with Python's | |
|
178 | atexit module, ensuring it's truly done as the kernel is done with all | |
|
179 | normal operation. | |
|
180 | """ | |
|
181 | 75 | pass |
|
182 | 76 | |
|
183 | 77 | |
|
184 | 78 | class IOPubChannelABC(ChannelABC): |
|
185 | """The SUB channel which listens for messages that the kernel publishes.""" | |
|
79 | """IOPubChannel ABC. | |
|
80 | ||
|
81 | The docstrings for this class can be found in the base implementation: | |
|
186 | 82 |
|
|
83 | `IPython.zmq.kernelmanager.IOPubChannel` | |
|
84 | """ | |
|
187 | 85 | |
|
188 | 86 | @abc.abstractmethod |
|
189 | 87 | def flush(self, timeout=1.0): |
|
190 | """Immediately processes all pending messages on the SUB channel. | |
|
191 | ||
|
192 | Callers should use this method to ensure that :method:`call_handlers` | |
|
193 | has been called for all messages that have been received on the | |
|
194 | 0MQ SUB socket of this channel. | |
|
195 | ||
|
196 | This method is thread safe. | |
|
197 | ||
|
198 | Parameters | |
|
199 | ---------- | |
|
200 | timeout : float, optional | |
|
201 | The maximum amount of time to spend flushing, in seconds. The | |
|
202 | default is one second. | |
|
203 | """ | |
|
204 | 88 | pass |
|
205 | 89 | |
|
206 | 90 | |
|
207 | 91 | class StdInChannelABC(ChannelABC): |
|
208 | """A reply channel to handle raw_input requests that the kernel makes.""" | |
|
92 | """StdInChannel ABC. | |
|
93 | ||
|
94 | The docstrings for this class can be found in the base implementation: | |
|
95 | ||
|
96 | `IPython.zmq.kernelmanager.StdInChannel` | |
|
97 | """ | |
|
209 | 98 | |
|
210 | 99 | @abc.abstractmethod |
|
211 | 100 | def input(self, string): |
|
212 | """Send a string of raw input to the kernel.""" | |
|
213 | 101 | pass |
|
214 | 102 | |
|
215 | 103 | |
|
216 | 104 | class HBChannelABC(ChannelABC): |
|
217 | """The heartbeat channel which monitors the kernel heartbeat.""" | |
|
105 | """HBChannel ABC. | |
|
106 | ||
|
107 | The docstrings for this class can be found in the base implementation: | |
|
108 | ||
|
109 | `IPython.zmq.kernelmanager.HBChannel` | |
|
110 | """ | |
|
218 | 111 | |
|
219 | 112 | @abc.abstractproperty |
|
220 | 113 | def time_to_dead(self): |
|
221 | 114 | pass |
|
222 | 115 | |
|
223 | 116 | @abc.abstractmethod |
|
224 | 117 | def pause(self): |
|
225 | """Pause the heartbeat.""" | |
|
226 | 118 | pass |
|
227 | 119 | |
|
228 | 120 | @abc.abstractmethod |
|
229 | 121 | def unpause(self): |
|
230 | """Unpause the heartbeat.""" | |
|
231 | 122 | pass |
|
232 | 123 | |
|
233 | 124 | @abc.abstractmethod |
|
234 | 125 | def is_beating(self): |
|
235 | """Is the heartbeat running and responsive (and not paused).""" | |
|
236 | 126 | pass |
|
237 | 127 | |
|
238 | 128 | |
|
239 | 129 | #----------------------------------------------------------------------------- |
|
240 | 130 | # Main kernel manager class |
|
241 | 131 | #----------------------------------------------------------------------------- |
|
242 | 132 | |
|
243 | 133 | class KernelManagerABC(object): |
|
244 | """ Manages a kernel for a frontend.""" | |
|
134 | """KernelManager ABC. | |
|
135 | ||
|
136 | The docstrings for this class can be found in the base implementation: | |
|
137 | ||
|
138 | `IPython.zmq.kernelmanager.KernelManager` | |
|
139 | """ | |
|
245 | 140 | |
|
246 | 141 | __metaclass__ = abc.ABCMeta |
|
247 | 142 | |
|
248 | 143 | @abc.abstractproperty |
|
249 | 144 | def kernel(self): |
|
250 | 145 | pass |
|
251 | 146 | |
|
252 | 147 | @abc.abstractproperty |
|
253 | 148 | def shell_channel_class(self): |
|
254 | 149 | pass |
|
255 | 150 | |
|
256 | 151 | @abc.abstractproperty |
|
257 | 152 | def iopub_channel_class(self): |
|
258 | 153 | pass |
|
259 | 154 | |
|
260 | 155 | @abc.abstractproperty |
|
261 | 156 | def hb_channel_class(self): |
|
262 | 157 | pass |
|
263 | 158 | |
|
264 | 159 | @abc.abstractproperty |
|
265 | 160 | def stdin_channel_class(self): |
|
266 | 161 | pass |
|
267 | 162 | |
|
268 | 163 | #-------------------------------------------------------------------------- |
|
269 | 164 | # Channel management methods: |
|
270 | 165 | #-------------------------------------------------------------------------- |
|
271 | 166 | |
|
272 | 167 | @abc.abstractmethod |
|
273 | 168 | def start_channels(self, shell=True, iopub=True, stdin=True, hb=True): |
|
274 | """Starts the channels for this kernel. | |
|
275 | ||
|
276 | This will create the channels if they do not exist and then start | |
|
277 | them. If port numbers of 0 are being used (random ports) then you | |
|
278 | must first call :method:`start_kernel`. If the channels have been | |
|
279 | stopped and you call this, :class:`RuntimeError` will be raised. | |
|
280 | """ | |
|
281 | 169 | pass |
|
282 | 170 | |
|
283 | 171 | @abc.abstractmethod |
|
284 | 172 | def stop_channels(self): |
|
285 | """Stops all the running channels for this kernel.""" | |
|
286 | 173 | pass |
|
287 | 174 | |
|
288 | 175 | @abc.abstractproperty |
|
289 | 176 | def channels_running(self): |
|
290 | """Are any of the channels created and running?""" | |
|
291 | 177 | pass |
|
292 | 178 | |
|
293 | 179 | @abc.abstractproperty |
|
294 | 180 | def shell_channel(self): |
|
295 | """Get the REQ socket channel object to make requests of the kernel.""" | |
|
296 | 181 | pass |
|
297 | 182 | |
|
298 | 183 | @abc.abstractproperty |
|
299 | 184 | def iopub_channel(self): |
|
300 | """Get the SUB socket channel object.""" | |
|
301 | 185 | pass |
|
302 | 186 | |
|
303 | 187 | @abc.abstractproperty |
|
304 | 188 | def stdin_channel(self): |
|
305 | """Get the REP socket channel object to handle stdin (raw_input).""" | |
|
306 | 189 | pass |
|
307 | 190 | |
|
308 | 191 | @abc.abstractproperty |
|
309 | 192 | def hb_channel(self): |
|
310 | """Get the heartbeat socket channel object to check that the | |
|
311 | kernel is alive.""" | |
|
312 | 193 | pass |
|
313 | 194 | |
|
314 | 195 | #-------------------------------------------------------------------------- |
|
315 | 196 | # Kernel management. |
|
316 | 197 | #-------------------------------------------------------------------------- |
|
317 | 198 | |
|
318 | 199 | @abc.abstractmethod |
|
319 | 200 | def start_kernel(self, **kw): |
|
320 | """Starts a kernel process and configures the manager to use it. | |
|
321 | ||
|
322 | If random ports (port=0) are being used, this method must be called | |
|
323 | before the channels are created. | |
|
324 | ||
|
325 | Parameters: | |
|
326 | ----------- | |
|
327 | launcher : callable, optional (default None) | |
|
328 | A custom function for launching the kernel process (generally a | |
|
329 | wrapper around ``entry_point.base_launch_kernel``). In most cases, | |
|
330 | it should not be necessary to use this parameter. | |
|
331 | ||
|
332 | **kw : optional | |
|
333 | See respective options for IPython and Python kernels. | |
|
334 | """ | |
|
335 | 201 | pass |
|
336 | 202 | |
|
337 | 203 | @abc.abstractmethod |
|
338 | 204 | def shutdown_kernel(self, now=False, restart=False): |
|
339 | """ Attempts to the stop the kernel process cleanly.""" | |
|
340 | 205 | pass |
|
341 | 206 | |
|
342 | 207 | @abc.abstractmethod |
|
343 | 208 | def restart_kernel(self, now=False, **kw): |
|
344 | """Restarts a kernel with the arguments that were used to launch it. | |
|
345 | ||
|
346 | If the old kernel was launched with random ports, the same ports will be | |
|
347 | used for the new kernel. | |
|
348 | ||
|
349 | Parameters | |
|
350 | ---------- | |
|
351 | now : bool, optional | |
|
352 | If True, the kernel is forcefully restarted *immediately*, without | |
|
353 | having a chance to do any cleanup action. Otherwise the kernel is | |
|
354 | given 1s to clean up before a forceful restart is issued. | |
|
355 | ||
|
356 | In all cases the kernel is restarted, the only difference is whether | |
|
357 | it is given a chance to perform a clean shutdown or not. | |
|
358 | ||
|
359 | **kw : optional | |
|
360 | Any options specified here will replace those used to launch the | |
|
361 | kernel. | |
|
362 | """ | |
|
363 | 209 | pass |
|
364 | 210 | |
|
365 | 211 | @abc.abstractproperty |
|
366 | 212 | def has_kernel(self): |
|
367 | """Returns whether a kernel process has been specified for the kernel | |
|
368 | manager. | |
|
369 | """ | |
|
370 | 213 | pass |
|
371 | 214 | |
|
372 | 215 | @abc.abstractmethod |
|
373 | 216 | def kill_kernel(self): |
|
374 | """ Kill the running kernel. | |
|
375 | ||
|
376 | This method blocks until the kernel process has terminated. | |
|
377 | """ | |
|
378 | 217 | pass |
|
379 | 218 | |
|
380 | 219 | @abc.abstractmethod |
|
381 | 220 | def interrupt_kernel(self): |
|
382 | """ Interrupts the kernel. | |
|
383 | ||
|
384 | Unlike ``signal_kernel``, this operation is well supported on all | |
|
385 | platforms. | |
|
386 | """ | |
|
387 | 221 | pass |
|
388 | 222 | |
|
389 | 223 | @abc.abstractmethod |
|
390 | 224 | def signal_kernel(self, signum): |
|
391 | """ Sends a signal to the kernel. | |
|
392 | ||
|
393 | Note that since only SIGTERM is supported on Windows, this function is | |
|
394 | only useful on Unix systems. | |
|
395 | """ | |
|
396 | 225 | pass |
|
397 | 226 | |
|
398 | 227 | @abc.abstractproperty |
|
399 | 228 | def is_alive(self): |
|
400 | """Is the kernel process still running?""" | |
|
401 | 229 | pass |
General Comments 0
You need to be logged in to leave comments.
Login now