##// END OF EJS Templates
update zmq shell magics...
MinRK -
Show More
@@ -1,539 +1,560 b''
1 1 """A ZMQ-based subclass of InteractiveShell.
2 2
3 3 This code is meant to ease the refactoring of the base InteractiveShell into
4 4 something with a cleaner architecture for 2-process use, without actually
5 5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 6 we subclass and override what we want to fix. Once this is working well, we
7 7 can go back to the base class and refactor the code for a cleaner inheritance
8 8 implementation that doesn't rely on so much monkeypatching.
9 9
10 10 But this lets us maintain a fully working IPython as we develop the new
11 11 machinery. This should thus be thought of as scaffolding.
12 12 """
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib
19 import inspect
20 19 import os
21 20 import sys
22 21 import time
23 from subprocess import Popen, PIPE
24 22
25 23 # System library imports
26 24 from zmq.eventloop import ioloop
27 25
28 26 # Our own
29 27 from IPython.core.interactiveshell import (
30 28 InteractiveShell, InteractiveShellABC
31 29 )
32 from IPython.core import page, pylabtools
30 from IPython.core import page
33 31 from IPython.core.autocall import ZMQExitAutocall
34 32 from IPython.core.displaypub import DisplayPublisher
35 from IPython.core.macro import Macro
36 from IPython.core.magics import MacroToEdit
33 from IPython.core.magics import MacroToEdit, CodeMagics
34 from IPython.core.magic import magics_class, line_magic, Magics
37 35 from IPython.core.payloadpage import install_payload_page
38 36 from IPython.lib.kernel import (
39 37 get_connection_file, get_connection_info, connect_qtconsole
40 38 )
41 39 from IPython.testing.skipdoctest import skip_doctest
42 40 from IPython.utils import io
43 41 from IPython.utils.jsonutil import json_clean
44 from IPython.utils.path import get_py_filename
45 42 from IPython.utils.process import arg_split
46 43 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
47 44 from IPython.utils.warn import warn, error
48 45 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
49 46 from IPython.zmq.session import extract_header
50 47 from session import Session
51 48
52 49 #-----------------------------------------------------------------------------
53 50 # Functions and classes
54 51 #-----------------------------------------------------------------------------
55 52
56 53 class ZMQDisplayPublisher(DisplayPublisher):
57 54 """A display publisher that publishes data using a ZeroMQ PUB socket."""
58 55
59 56 session = Instance(Session)
60 57 pub_socket = Instance('zmq.Socket')
61 58 parent_header = Dict({})
62 59 topic = CBytes(b'displaypub')
63 60
64 61 def set_parent(self, parent):
65 62 """Set the parent for outbound messages."""
66 63 self.parent_header = extract_header(parent)
67 64
68 65 def _flush_streams(self):
69 66 """flush IO Streams prior to display"""
70 67 sys.stdout.flush()
71 68 sys.stderr.flush()
72 69
73 70 def publish(self, source, data, metadata=None):
74 71 self._flush_streams()
75 72 if metadata is None:
76 73 metadata = {}
77 74 self._validate_data(source, data, metadata)
78 75 content = {}
79 76 content['source'] = source
80 77 content['data'] = _encode_binary(data)
81 78 content['metadata'] = metadata
82 79 self.session.send(
83 80 self.pub_socket, u'display_data', json_clean(content),
84 81 parent=self.parent_header, ident=self.topic,
85 82 )
86 83
87 84 def clear_output(self, stdout=True, stderr=True, other=True):
88 85 content = dict(stdout=stdout, stderr=stderr, other=other)
89 86
90 87 if stdout:
91 88 print('\r', file=sys.stdout, end='')
92 89 if stderr:
93 90 print('\r', file=sys.stderr, end='')
94 91
95 92 self._flush_streams()
96 93
97 94 self.session.send(
98 95 self.pub_socket, u'clear_output', content,
99 96 parent=self.parent_header, ident=self.topic,
100 97 )
101 98
102 class ZMQInteractiveShell(InteractiveShell):
103 """A subclass of InteractiveShell for ZMQ."""
104
105 displayhook_class = Type(ZMQShellDisplayHook)
106 display_pub_class = Type(ZMQDisplayPublisher)
107
108 # Override the traitlet in the parent class, because there's no point using
109 # readline for the kernel. Can be removed when the readline code is moved
110 # to the terminal frontend.
111 colors_force = CBool(True)
112 readline_use = CBool(False)
113 # autoindent has no meaning in a zmqshell, and attempting to enable it
114 # will print a warning in the absence of readline.
115 autoindent = CBool(False)
116
117 exiter = Instance(ZMQExitAutocall)
118 def _exiter_default(self):
119 return ZMQExitAutocall(self)
120
121 def _exit_now_changed(self, name, old, new):
122 """stop eventloop when exit_now fires"""
123 if new:
124 loop = ioloop.IOLoop.instance()
125 loop.add_timeout(time.time()+0.1, loop.stop)
126
127 keepkernel_on_exit = None
128
129 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
130 # interactive input being read; we provide event loop support in ipkernel
131 from .eventloops import enable_gui
132 enable_gui = staticmethod(enable_gui)
133
134 def init_environment(self):
135 """Configure the user's environment.
136
137 """
138 env = os.environ
139 # These two ensure 'ls' produces nice coloring on BSD-derived systems
140 env['TERM'] = 'xterm-color'
141 env['CLICOLOR'] = '1'
142 # Since normal pagers don't work at all (over pexpect we don't have
143 # single-key control of the subprocess), try to disable paging in
144 # subprocesses as much as possible.
145 env['PAGER'] = 'cat'
146 env['GIT_PAGER'] = 'cat'
147
148 # And install the payload version of page.
149 install_payload_page()
150
151 def auto_rewrite_input(self, cmd):
152 """Called to show the auto-rewritten input for autocall and friends.
153
154 FIXME: this payload is currently not correctly processed by the
155 frontend.
156 """
157 new = self.prompt_manager.render('rewrite') + cmd
158 payload = dict(
159 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
160 transformed_input=new,
161 )
162 self.payload_manager.write_payload(payload)
163
164 def ask_exit(self):
165 """Engage the exit actions."""
166 self.exit_now = True
167 payload = dict(
168 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
169 exit=True,
170 keepkernel=self.keepkernel_on_exit,
171 )
172 self.payload_manager.write_payload(payload)
173
174 def _showtraceback(self, etype, evalue, stb):
175
176 exc_content = {
177 u'traceback' : stb,
178 u'ename' : unicode(etype.__name__),
179 u'evalue' : unicode(evalue)
180 }
181
182 dh = self.displayhook
183 # Send exception info over pub socket for other clients than the caller
184 # to pick up
185 topic = None
186 if dh.topic:
187 topic = dh.topic.replace(b'pyout', b'pyerr')
188
189 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
190
191 # FIXME - Hack: store exception info in shell object. Right now, the
192 # caller is reading this info after the fact, we need to fix this logic
193 # to remove this hack. Even uglier, we need to store the error status
194 # here, because in the main loop, the logic that sets it is being
195 # skipped because runlines swallows the exceptions.
196 exc_content[u'status'] = u'error'
197 self._reply_content = exc_content
198 # /FIXME
199
200 return exc_content
201
99 @magics_class
100 class KernelMagics(Magics):
202 101 #------------------------------------------------------------------------
203 102 # Magic overrides
204 103 #------------------------------------------------------------------------
205 104 # Once the base class stops inheriting from magic, this code needs to be
206 105 # moved into a separate machinery as well. For now, at least isolate here
207 106 # the magics which this class needs to implement differently from the base
208 107 # class, or that are unique to it.
209 108
210 def magic_doctest_mode(self,parameter_s=''):
109 @line_magic
110 def doctest_mode(self, parameter_s=''):
211 111 """Toggle doctest mode on and off.
212 112
213 113 This mode is intended to make IPython behave as much as possible like a
214 114 plain Python shell, from the perspective of how its prompts, exceptions
215 115 and output look. This makes it easy to copy and paste parts of a
216 116 session into doctests. It does so by:
217 117
218 118 - Changing the prompts to the classic ``>>>`` ones.
219 119 - Changing the exception reporting mode to 'Plain'.
220 120 - Disabling pretty-printing of output.
221 121
222 122 Note that IPython also supports the pasting of code snippets that have
223 123 leading '>>>' and '...' prompts in them. This means that you can paste
224 124 doctests from files or docstrings (even if they have leading
225 125 whitespace), and the code will execute correctly. You can then use
226 126 '%history -t' to see the translated history; this will give you the
227 127 input after removal of all the leading prompts and whitespace, which
228 128 can be pasted back into an editor.
229 129
230 130 With these features, you can switch into this mode easily whenever you
231 131 need to do testing and changes to doctests, without having to leave
232 132 your existing IPython session.
233 133 """
234 134
235 135 from IPython.utils.ipstruct import Struct
236 136
237 137 # Shorthands
238 138 shell = self.shell
239 139 disp_formatter = self.shell.display_formatter
240 140 ptformatter = disp_formatter.formatters['text/plain']
241 141 # dstore is a data store kept in the instance metadata bag to track any
242 142 # changes we make, so we can undo them later.
243 143 dstore = shell.meta.setdefault('doctest_mode', Struct())
244 144 save_dstore = dstore.setdefault
245 145
246 146 # save a few values we'll need to recover later
247 147 mode = save_dstore('mode', False)
248 148 save_dstore('rc_pprint', ptformatter.pprint)
249 149 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
250 150 save_dstore('xmode', shell.InteractiveTB.mode)
251 151
252 152 if mode == False:
253 153 # turn on
254 154 ptformatter.pprint = False
255 155 disp_formatter.plain_text_only = True
256 shell.magic_xmode('Plain')
156 shell.magic('xmode Plain')
257 157 else:
258 158 # turn off
259 159 ptformatter.pprint = dstore.rc_pprint
260 160 disp_formatter.plain_text_only = dstore.rc_plain_text_only
261 shell.magic_xmode(dstore.xmode)
161 shell.magic("xmode " + dstore.xmode)
262 162
263 163 # Store new mode and inform on console
264 164 dstore.mode = bool(1-int(mode))
265 165 mode_label = ['OFF','ON'][dstore.mode]
266 166 print('Doctest mode is:', mode_label)
267 167
268 168 # Send the payload back so that clients can modify their prompt display
269 169 payload = dict(
270 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
170 source='IPython.zmq.zmqshell.ZMQInteractiveShell.doctest_mode',
271 171 mode=dstore.mode)
272 self.payload_manager.write_payload(payload)
172 shell.payload_manager.write_payload(payload)
173
174
175 _find_edit_target = CodeMagics._find_edit_target
273 176
274 177 @skip_doctest
275 def magic_edit(self,parameter_s='',last_call=['','']):
178 @line_magic
179 def edit(self, parameter_s='', last_call=['','']):
276 180 """Bring up an editor and execute the resulting code.
277 181
278 182 Usage:
279 183 %edit [options] [args]
280 184
281 185 %edit runs an external text editor. You will need to set the command for
282 186 this editor via the ``TerminalInteractiveShell.editor`` option in your
283 187 configuration file before it will work.
284 188
285 189 This command allows you to conveniently edit multi-line code right in
286 190 your IPython session.
287 191
288 192 If called without arguments, %edit opens up an empty editor with a
289 193 temporary file and will execute the contents of this file when you
290 194 close it (don't forget to save it!).
291 195
292 196
293 197 Options:
294 198
295 199 -n <number>: open the editor at a specified line number. By default,
296 200 the IPython editor hook uses the unix syntax 'editor +N filename', but
297 201 you can configure this by providing your own modified hook if your
298 202 favorite editor supports line-number specifications with a different
299 203 syntax.
300 204
301 205 -p: this will call the editor with the same data as the previous time
302 206 it was used, regardless of how long ago (in your current session) it
303 207 was.
304 208
305 209 -r: use 'raw' input. This option only applies to input taken from the
306 210 user's history. By default, the 'processed' history is used, so that
307 211 magics are loaded in their transformed version to valid Python. If
308 212 this option is given, the raw input as typed as the command line is
309 213 used instead. When you exit the editor, it will be executed by
310 214 IPython's own processor.
311 215
312 216 -x: do not execute the edited code immediately upon exit. This is
313 217 mainly useful if you are editing programs which need to be called with
314 218 command line arguments, which you can then do using %run.
315 219
316 220
317 221 Arguments:
318 222
319 223 If arguments are given, the following possibilites exist:
320 224
321 225 - The arguments are numbers or pairs of colon-separated numbers (like
322 226 1 4:8 9). These are interpreted as lines of previous input to be
323 227 loaded into the editor. The syntax is the same of the %macro command.
324 228
325 229 - If the argument doesn't start with a number, it is evaluated as a
326 230 variable and its contents loaded into the editor. You can thus edit
327 231 any string which contains python code (including the result of
328 232 previous edits).
329 233
330 234 - If the argument is the name of an object (other than a string),
331 235 IPython will try to locate the file where it was defined and open the
332 236 editor at the point where it is defined. You can use `%edit function`
333 237 to load an editor exactly at the point where 'function' is defined,
334 238 edit it and have the file be executed automatically.
335 239
336 240 If the object is a macro (see %macro for details), this opens up your
337 241 specified editor with a temporary file containing the macro's data.
338 242 Upon exit, the macro is reloaded with the contents of the file.
339 243
340 244 Note: opening at an exact line is only supported under Unix, and some
341 245 editors (like kedit and gedit up to Gnome 2.8) do not understand the
342 246 '+NUMBER' parameter necessary for this feature. Good editors like
343 247 (X)Emacs, vi, jed, pico and joe all do.
344 248
345 249 - If the argument is not found as a variable, IPython will look for a
346 250 file with that name (adding .py if necessary) and load it into the
347 251 editor. It will execute its contents with execfile() when you exit,
348 252 loading any code in the file into your interactive namespace.
349 253
350 254 After executing your code, %edit will return as output the code you
351 255 typed in the editor (except when it was an existing file). This way
352 256 you can reload the code in further invocations of %edit as a variable,
353 257 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
354 258 the output.
355 259
356 260 Note that %edit is also available through the alias %ed.
357 261
358 262 This is an example of creating a simple function inside the editor and
359 263 then modifying it. First, start up the editor:
360 264
361 265 In [1]: ed
362 266 Editing... done. Executing edited code...
363 267 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
364 268
365 269 We can then call the function foo():
366 270
367 271 In [2]: foo()
368 272 foo() was defined in an editing session
369 273
370 274 Now we edit foo. IPython automatically loads the editor with the
371 275 (temporary) file where foo() was previously defined:
372 276
373 277 In [3]: ed foo
374 278 Editing... done. Executing edited code...
375 279
376 280 And if we call foo() again we get the modified version:
377 281
378 282 In [4]: foo()
379 283 foo() has now been changed!
380 284
381 285 Here is an example of how to edit a code snippet successive
382 286 times. First we call the editor:
383 287
384 288 In [5]: ed
385 289 Editing... done. Executing edited code...
386 290 hello
387 291 Out[5]: "print 'hello'n"
388 292
389 293 Now we call it again with the previous output (stored in _):
390 294
391 295 In [6]: ed _
392 296 Editing... done. Executing edited code...
393 297 hello world
394 298 Out[6]: "print 'hello world'n"
395 299
396 300 Now we call it with the output #8 (stored in _8, also as Out[8]):
397 301
398 302 In [7]: ed _8
399 303 Editing... done. Executing edited code...
400 304 hello again
401 305 Out[7]: "print 'hello again'n"
402 306 """
403 307
404 308 opts,args = self.parse_options(parameter_s,'prn:')
405 309
406 310 try:
407 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
311 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
408 312 except MacroToEdit as e:
409 313 # TODO: Implement macro editing over 2 processes.
410 314 print("Macro editing not yet implemented in 2-process model.")
411 315 return
412 316
413 317 # Make sure we send to the client an absolute path, in case the working
414 318 # directory of client and kernel don't match
415 319 filename = os.path.abspath(filename)
416 320
417 321 payload = {
418 322 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
419 323 'filename' : filename,
420 324 'line_number' : lineno
421 325 }
422 self.payload_manager.write_payload(payload)
326 self.shell.payload_manager.write_payload(payload)
423 327
424 328 # A few magics that are adapted to the specifics of using pexpect and a
425 329 # remote terminal
426 330
427 def magic_clear(self, arg_s):
331 @line_magic
332 def clear(self, arg_s):
428 333 """Clear the terminal."""
429 334 if os.name == 'posix':
430 335 self.shell.system("clear")
431 336 else:
432 337 self.shell.system("cls")
433 338
434 339 if os.name == 'nt':
435 340 # This is the usual name in windows
436 magic_cls = magic_clear
341 cls = line_magic('cls')(clear)
437 342
438 343 # Terminal pagers won't work over pexpect, but we do have our own pager
439 344
440 def magic_less(self, arg_s):
345 @line_magic
346 def less(self, arg_s):
441 347 """Show a file through the pager.
442 348
443 349 Files ending in .py are syntax-highlighted."""
444 350 cont = open(arg_s).read()
445 351 if arg_s.endswith('.py'):
446 352 cont = self.shell.pycolorize(cont)
447 353 page.page(cont)
448 354
449 magic_more = magic_less
355 more = line_magic('more')(less)
450 356
451 357 # Man calls a pager, so we also need to redefine it
452 358 if os.name == 'posix':
453 def magic_man(self, arg_s):
359 @line_magic
360 def man(self, arg_s):
454 361 """Find the man page for the given command and display in pager."""
455 362 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
456 363 split=False))
457 364
458 365 # FIXME: this is specific to the GUI, so we should let the gui app load
459 366 # magics at startup that are only for the gui. Once the gui app has proper
460 367 # profile and configuration management, we can have it initialize a kernel
461 368 # with a special config file that provides these.
462 def magic_guiref(self, arg_s):
369
370 @line_magic
371 def guiref(self, arg_s):
463 372 """Show a basic reference about the GUI console."""
464 373 from IPython.core.usage import gui_reference
465 374 page.page(gui_reference, auto_html=True)
466 375
467 def magic_connect_info(self, arg_s):
376 @line_magic
377 def connect_info(self, arg_s):
468 378 """Print information for connecting other clients to this kernel
469 379
470 380 It will print the contents of this session's connection file, as well as
471 381 shortcuts for local clients.
472 382
473 383 In the simplest case, when called from the most recently launched kernel,
474 384 secondary clients can be connected, simply with:
475 385
476 386 $> ipython <app> --existing
477 387
478 388 """
479 389
480 390 from IPython.core.application import BaseIPythonApplication as BaseIPApp
481 391
482 392 if BaseIPApp.initialized():
483 393 app = BaseIPApp.instance()
484 394 security_dir = app.profile_dir.security_dir
485 395 profile = app.profile
486 396 else:
487 397 profile = 'default'
488 398 security_dir = ''
489 399
490 400 try:
491 401 connection_file = get_connection_file()
492 402 info = get_connection_info(unpack=False)
493 403 except Exception as e:
494 404 error("Could not get connection info: %r" % e)
495 405 return
496 406
497 407 # add profile flag for non-default profile
498 408 profile_flag = "--profile %s" % profile if profile != 'default' else ""
499 409
500 410 # if it's in the security dir, truncate to basename
501 411 if security_dir == os.path.dirname(connection_file):
502 412 connection_file = os.path.basename(connection_file)
503 413
504 414
505 415 print (info + '\n')
506 416 print ("Paste the above JSON into a file, and connect with:\n"
507 417 " $> ipython <app> --existing <file>\n"
508 418 "or, if you are local, you can connect with just:\n"
509 419 " $> ipython <app> --existing {0} {1}\n"
510 420 "or even just:\n"
511 421 " $> ipython <app> --existing {1}\n"
512 422 "if this is the most recent IPython session you have started.".format(
513 423 connection_file, profile_flag
514 424 )
515 425 )
516 426
517 def magic_qtconsole(self, arg_s):
427 @line_magic
428 def qtconsole(self, arg_s):
518 429 """Open a qtconsole connected to this kernel.
519 430
520 431 Useful for connecting a qtconsole to running notebooks, for better
521 432 debugging.
522 433 """
523 434 try:
524 435 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
525 436 except Exception as e:
526 437 error("Could not start qtconsole: %r" % e)
527 438 return
528 439
440
441 class ZMQInteractiveShell(InteractiveShell):
442 """A subclass of InteractiveShell for ZMQ."""
443
444 displayhook_class = Type(ZMQShellDisplayHook)
445 display_pub_class = Type(ZMQDisplayPublisher)
446
447 # Override the traitlet in the parent class, because there's no point using
448 # readline for the kernel. Can be removed when the readline code is moved
449 # to the terminal frontend.
450 colors_force = CBool(True)
451 readline_use = CBool(False)
452 # autoindent has no meaning in a zmqshell, and attempting to enable it
453 # will print a warning in the absence of readline.
454 autoindent = CBool(False)
455
456 exiter = Instance(ZMQExitAutocall)
457 def _exiter_default(self):
458 return ZMQExitAutocall(self)
459
460 def _exit_now_changed(self, name, old, new):
461 """stop eventloop when exit_now fires"""
462 if new:
463 loop = ioloop.IOLoop.instance()
464 loop.add_timeout(time.time()+0.1, loop.stop)
465
466 keepkernel_on_exit = None
467
468 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
469 # interactive input being read; we provide event loop support in ipkernel
470 from .eventloops import enable_gui
471 enable_gui = staticmethod(enable_gui)
472
473 def init_environment(self):
474 """Configure the user's environment.
475
476 """
477 env = os.environ
478 # These two ensure 'ls' produces nice coloring on BSD-derived systems
479 env['TERM'] = 'xterm-color'
480 env['CLICOLOR'] = '1'
481 # Since normal pagers don't work at all (over pexpect we don't have
482 # single-key control of the subprocess), try to disable paging in
483 # subprocesses as much as possible.
484 env['PAGER'] = 'cat'
485 env['GIT_PAGER'] = 'cat'
486
487 # And install the payload version of page.
488 install_payload_page()
489
490 def auto_rewrite_input(self, cmd):
491 """Called to show the auto-rewritten input for autocall and friends.
492
493 FIXME: this payload is currently not correctly processed by the
494 frontend.
495 """
496 new = self.prompt_manager.render('rewrite') + cmd
497 payload = dict(
498 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
499 transformed_input=new,
500 )
501 self.payload_manager.write_payload(payload)
502
503 def ask_exit(self):
504 """Engage the exit actions."""
505 self.exit_now = True
506 payload = dict(
507 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
508 exit=True,
509 keepkernel=self.keepkernel_on_exit,
510 )
511 self.payload_manager.write_payload(payload)
512
513 def _showtraceback(self, etype, evalue, stb):
514
515 exc_content = {
516 u'traceback' : stb,
517 u'ename' : unicode(etype.__name__),
518 u'evalue' : unicode(evalue)
519 }
520
521 dh = self.displayhook
522 # Send exception info over pub socket for other clients than the caller
523 # to pick up
524 topic = None
525 if dh.topic:
526 topic = dh.topic.replace(b'pyout', b'pyerr')
527
528 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
529
530 # FIXME - Hack: store exception info in shell object. Right now, the
531 # caller is reading this info after the fact, we need to fix this logic
532 # to remove this hack. Even uglier, we need to store the error status
533 # here, because in the main loop, the logic that sets it is being
534 # skipped because runlines swallows the exceptions.
535 exc_content[u'status'] = u'error'
536 self._reply_content = exc_content
537 # /FIXME
538
539 return exc_content
540
529 541 def set_next_input(self, text):
530 542 """Send the specified text to the frontend to be presented at the next
531 543 input cell."""
532 544 payload = dict(
533 545 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
534 546 text=text
535 547 )
536 548 self.payload_manager.write_payload(payload)
549
550 #-------------------------------------------------------------------------
551 # Things related to magics
552 #-------------------------------------------------------------------------
553
554 def init_magics(self):
555 super(ZMQInteractiveShell, self).init_magics()
556 self.register_magics(KernelMagics)
557
537 558
538 559
539 560 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now