##// END OF EJS Templates
quiet error messages instead of tracebacks in %pylab/%gui...
MinRK -
Show More
@@ -1,612 +1,616 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Subclass of InteractiveShell for terminal based frontends."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2010 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 import __builtin__
18 18 import bdb
19 19 import os
20 20 import re
21 21 import sys
22 22
23 23 try:
24 24 from contextlib import nested
25 25 except:
26 26 from IPython.utils.nested_context import nested
27 27
28 28 from IPython.core.error import TryNext
29 29 from IPython.core.usage import interactive_usage, default_banner
30 30 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
31 31 from IPython.lib.inputhook import enable_gui
32 32 from IPython.lib.pylabtools import pylab_activate
33 33 from IPython.testing.skipdoctest import skip_doctest
34 34 from IPython.utils import py3compat
35 35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
36 36 from IPython.utils.process import abbrev_cwd
37 37 from IPython.utils.warn import warn
38 38 from IPython.utils.text import num_ini_spaces
39 39 from IPython.utils.traitlets import Int, CBool, Unicode
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Utilities
43 43 #-----------------------------------------------------------------------------
44 44
45 45 def get_default_editor():
46 46 try:
47 47 ed = os.environ['EDITOR']
48 48 except KeyError:
49 49 if os.name == 'posix':
50 50 ed = 'vi' # the only one guaranteed to be there!
51 51 else:
52 52 ed = 'notepad' # same in Windows!
53 53 return ed
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Main class
57 57 #-----------------------------------------------------------------------------
58 58
59 59 class TerminalInteractiveShell(InteractiveShell):
60 60
61 61 autoedit_syntax = CBool(False, config=True,
62 62 help="auto editing of files with syntax errors.")
63 63 banner = Unicode('')
64 64 banner1 = Unicode(default_banner, config=True,
65 65 help="""The part of the banner to be printed before the profile"""
66 66 )
67 67 banner2 = Unicode('', config=True,
68 68 help="""The part of the banner to be printed after the profile"""
69 69 )
70 70 confirm_exit = CBool(True, config=True,
71 71 help="""
72 72 Set to confirm when you try to exit IPython with an EOF (Control-D
73 73 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
74 74 you can force a direct exit without any confirmation.""",
75 75 )
76 76 # This display_banner only controls whether or not self.show_banner()
77 77 # is called when mainloop/interact are called. The default is False
78 78 # because for the terminal based application, the banner behavior
79 79 # is controlled by Global.display_banner, which IPythonApp looks at
80 80 # to determine if *it* should call show_banner() by hand or not.
81 81 display_banner = CBool(False) # This isn't configurable!
82 82 embedded = CBool(False)
83 83 embedded_active = CBool(False)
84 84 editor = Unicode(get_default_editor(), config=True,
85 85 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
86 86 )
87 87 pager = Unicode('less', config=True,
88 88 help="The shell program to be used for paging.")
89 89
90 90 screen_length = Int(0, config=True,
91 91 help=
92 92 """Number of lines of your screen, used to control printing of very
93 93 long strings. Strings longer than this number of lines will be sent
94 94 through a pager instead of directly printed. The default value for
95 95 this is 0, which means IPython will auto-detect your screen size every
96 96 time it needs to print certain potentially long strings (this doesn't
97 97 change the behavior of the 'print' keyword, it's only triggered
98 98 internally). If for some reason this isn't working well (it needs
99 99 curses support), specify it yourself. Otherwise don't change the
100 100 default.""",
101 101 )
102 102 term_title = CBool(False, config=True,
103 103 help="Enable auto setting the terminal title."
104 104 )
105 105
106 106 def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
107 107 user_global_ns=None, custom_exceptions=((),None),
108 108 usage=None, banner1=None, banner2=None,
109 109 display_banner=None):
110 110
111 111 super(TerminalInteractiveShell, self).__init__(
112 112 config=config, profile_dir=profile_dir, user_ns=user_ns,
113 113 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
114 114 )
115 115 # use os.system instead of utils.process.system by default, except on Windows
116 116 if os.name == 'nt':
117 117 self.system = self.system_piped
118 118 else:
119 119 self.system = self.system_raw
120 120
121 121 self.init_term_title()
122 122 self.init_usage(usage)
123 123 self.init_banner(banner1, banner2, display_banner)
124 124
125 125 #-------------------------------------------------------------------------
126 126 # Things related to the terminal
127 127 #-------------------------------------------------------------------------
128 128
129 129 @property
130 130 def usable_screen_length(self):
131 131 if self.screen_length == 0:
132 132 return 0
133 133 else:
134 134 num_lines_bot = self.separate_in.count('\n')+1
135 135 return self.screen_length - num_lines_bot
136 136
137 137 def init_term_title(self):
138 138 # Enable or disable the terminal title.
139 139 if self.term_title:
140 140 toggle_set_term_title(True)
141 141 set_term_title('IPython: ' + abbrev_cwd())
142 142 else:
143 143 toggle_set_term_title(False)
144 144
145 145 #-------------------------------------------------------------------------
146 146 # Things related to aliases
147 147 #-------------------------------------------------------------------------
148 148
149 149 def init_alias(self):
150 150 # The parent class defines aliases that can be safely used with any
151 151 # frontend.
152 152 super(TerminalInteractiveShell, self).init_alias()
153 153
154 154 # Now define aliases that only make sense on the terminal, because they
155 155 # need direct access to the console in a way that we can't emulate in
156 156 # GUI or web frontend
157 157 if os.name == 'posix':
158 158 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
159 159 ('man', 'man')]
160 160 elif os.name == 'nt':
161 161 aliases = [('cls', 'cls')]
162 162
163 163
164 164 for name, cmd in aliases:
165 165 self.alias_manager.define_alias(name, cmd)
166 166
167 167 #-------------------------------------------------------------------------
168 168 # Things related to the banner and usage
169 169 #-------------------------------------------------------------------------
170 170
171 171 def _banner1_changed(self):
172 172 self.compute_banner()
173 173
174 174 def _banner2_changed(self):
175 175 self.compute_banner()
176 176
177 177 def _term_title_changed(self, name, new_value):
178 178 self.init_term_title()
179 179
180 180 def init_banner(self, banner1, banner2, display_banner):
181 181 if banner1 is not None:
182 182 self.banner1 = banner1
183 183 if banner2 is not None:
184 184 self.banner2 = banner2
185 185 if display_banner is not None:
186 186 self.display_banner = display_banner
187 187 self.compute_banner()
188 188
189 189 def show_banner(self, banner=None):
190 190 if banner is None:
191 191 banner = self.banner
192 192 self.write(banner)
193 193
194 194 def compute_banner(self):
195 195 self.banner = self.banner1
196 196 if self.profile and self.profile != 'default':
197 197 self.banner += '\nIPython profile: %s\n' % self.profile
198 198 if self.banner2:
199 199 self.banner += '\n' + self.banner2
200 200
201 201 def init_usage(self, usage=None):
202 202 if usage is None:
203 203 self.usage = interactive_usage
204 204 else:
205 205 self.usage = usage
206 206
207 207 #-------------------------------------------------------------------------
208 208 # Mainloop and code execution logic
209 209 #-------------------------------------------------------------------------
210 210
211 211 def mainloop(self, display_banner=None):
212 212 """Start the mainloop.
213 213
214 214 If an optional banner argument is given, it will override the
215 215 internally created default banner.
216 216 """
217 217
218 218 with nested(self.builtin_trap, self.display_trap):
219 219
220 220 while 1:
221 221 try:
222 222 self.interact(display_banner=display_banner)
223 223 #self.interact_with_readline()
224 224 # XXX for testing of a readline-decoupled repl loop, call
225 225 # interact_with_readline above
226 226 break
227 227 except KeyboardInterrupt:
228 228 # this should not be necessary, but KeyboardInterrupt
229 229 # handling seems rather unpredictable...
230 230 self.write("\nKeyboardInterrupt in interact()\n")
231 231
232 232 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
233 233 """Store multiple lines as a single entry in history"""
234 234 if self.multiline_history and self.has_readline:
235 235 hlen = self.readline.get_current_history_length()
236 236 for i in range(hlen - hlen_before_cell):
237 237 self.readline.remove_history_item(hlen - i - 1)
238 238 stdin_encoding = sys.stdin.encoding or "utf-8"
239 239 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
240 240 stdin_encoding))
241 241
242 242 def interact(self, display_banner=None):
243 243 """Closely emulate the interactive Python console."""
244 244
245 245 # batch run -> do not interact
246 246 if self.exit_now:
247 247 return
248 248
249 249 if display_banner is None:
250 250 display_banner = self.display_banner
251 251
252 252 if isinstance(display_banner, basestring):
253 253 self.show_banner(display_banner)
254 254 elif display_banner:
255 255 self.show_banner()
256 256
257 257 more = False
258 258 hlen_before_cell = self.readline.get_current_history_length()
259 259
260 260 # Mark activity in the builtins
261 261 __builtin__.__dict__['__IPYTHON__active'] += 1
262 262
263 263 if self.has_readline:
264 264 self.readline_startup_hook(self.pre_readline)
265 265 # exit_now is set by a call to %Exit or %Quit, through the
266 266 # ask_exit callback.
267 267
268 268 while not self.exit_now:
269 269 self.hooks.pre_prompt_hook()
270 270 if more:
271 271 try:
272 272 prompt = self.hooks.generate_prompt(True)
273 273 except:
274 274 self.showtraceback()
275 275 if self.autoindent:
276 276 self.rl_do_indent = True
277 277
278 278 else:
279 279 try:
280 280 prompt = self.hooks.generate_prompt(False)
281 281 except:
282 282 self.showtraceback()
283 283 try:
284 284 line = self.raw_input(prompt)
285 285 if self.exit_now:
286 286 # quick exit on sys.std[in|out] close
287 287 break
288 288 if self.autoindent:
289 289 self.rl_do_indent = False
290 290
291 291 except KeyboardInterrupt:
292 292 #double-guard against keyboardinterrupts during kbdint handling
293 293 try:
294 294 self.write('\nKeyboardInterrupt\n')
295 295 source_raw = self.input_splitter.source_raw_reset()[1]
296 296 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
297 297 hlen_before_cell = self.readline.get_current_history_length()
298 298 more = False
299 299 except KeyboardInterrupt:
300 300 pass
301 301 except EOFError:
302 302 if self.autoindent:
303 303 self.rl_do_indent = False
304 304 if self.has_readline:
305 305 self.readline_startup_hook(None)
306 306 self.write('\n')
307 307 self.exit()
308 308 except bdb.BdbQuit:
309 309 warn('The Python debugger has exited with a BdbQuit exception.\n'
310 310 'Because of how pdb handles the stack, it is impossible\n'
311 311 'for IPython to properly format this particular exception.\n'
312 312 'IPython will resume normal operation.')
313 313 except:
314 314 # exceptions here are VERY RARE, but they can be triggered
315 315 # asynchronously by signal handlers, for example.
316 316 self.showtraceback()
317 317 else:
318 318 self.input_splitter.push(line)
319 319 more = self.input_splitter.push_accepts_more()
320 320 if (self.SyntaxTB.last_syntax_error and
321 321 self.autoedit_syntax):
322 322 self.edit_syntax_error()
323 323 if not more:
324 324 source_raw = self.input_splitter.source_raw_reset()[1]
325 325 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
326 326 hlen_before_cell = self.readline.get_current_history_length()
327 327 self.run_cell(source_raw, store_history=True)
328 328
329 329 # We are off again...
330 330 __builtin__.__dict__['__IPYTHON__active'] -= 1
331 331
332 332 # Turn off the exit flag, so the mainloop can be restarted if desired
333 333 self.exit_now = False
334 334
335 335 def raw_input(self, prompt=''):
336 336 """Write a prompt and read a line.
337 337
338 338 The returned line does not include the trailing newline.
339 339 When the user enters the EOF key sequence, EOFError is raised.
340 340
341 341 Optional inputs:
342 342
343 343 - prompt(''): a string to be printed to prompt the user.
344 344
345 345 - continue_prompt(False): whether this line is the first one or a
346 346 continuation in a sequence of inputs.
347 347 """
348 348 # Code run by the user may have modified the readline completer state.
349 349 # We must ensure that our completer is back in place.
350 350
351 351 if self.has_readline:
352 352 self.set_readline_completer()
353 353
354 354 try:
355 355 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
356 356 except ValueError:
357 357 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
358 358 " or sys.stdout.close()!\nExiting IPython!")
359 359 self.ask_exit()
360 360 return ""
361 361
362 362 # Try to be reasonably smart about not re-indenting pasted input more
363 363 # than necessary. We do this by trimming out the auto-indent initial
364 364 # spaces, if the user's actual input started itself with whitespace.
365 365 if self.autoindent:
366 366 if num_ini_spaces(line) > self.indent_current_nsp:
367 367 line = line[self.indent_current_nsp:]
368 368 self.indent_current_nsp = 0
369 369
370 370 return line
371 371
372 372 #-------------------------------------------------------------------------
373 373 # Methods to support auto-editing of SyntaxErrors.
374 374 #-------------------------------------------------------------------------
375 375
376 376 def edit_syntax_error(self):
377 377 """The bottom half of the syntax error handler called in the main loop.
378 378
379 379 Loop until syntax error is fixed or user cancels.
380 380 """
381 381
382 382 while self.SyntaxTB.last_syntax_error:
383 383 # copy and clear last_syntax_error
384 384 err = self.SyntaxTB.clear_err_state()
385 385 if not self._should_recompile(err):
386 386 return
387 387 try:
388 388 # may set last_syntax_error again if a SyntaxError is raised
389 389 self.safe_execfile(err.filename,self.user_ns)
390 390 except:
391 391 self.showtraceback()
392 392 else:
393 393 try:
394 394 f = file(err.filename)
395 395 try:
396 396 # This should be inside a display_trap block and I
397 397 # think it is.
398 398 sys.displayhook(f.read())
399 399 finally:
400 400 f.close()
401 401 except:
402 402 self.showtraceback()
403 403
404 404 def _should_recompile(self,e):
405 405 """Utility routine for edit_syntax_error"""
406 406
407 407 if e.filename in ('<ipython console>','<input>','<string>',
408 408 '<console>','<BackgroundJob compilation>',
409 409 None):
410 410
411 411 return False
412 412 try:
413 413 if (self.autoedit_syntax and
414 414 not self.ask_yes_no('Return to editor to correct syntax error? '
415 415 '[Y/n] ','y')):
416 416 return False
417 417 except EOFError:
418 418 return False
419 419
420 420 def int0(x):
421 421 try:
422 422 return int(x)
423 423 except TypeError:
424 424 return 0
425 425 # always pass integer line and offset values to editor hook
426 426 try:
427 427 self.hooks.fix_error_editor(e.filename,
428 428 int0(e.lineno),int0(e.offset),e.msg)
429 429 except TryNext:
430 430 warn('Could not open editor')
431 431 return False
432 432 return True
433 433
434 434 #-------------------------------------------------------------------------
435 435 # Things related to GUI support and pylab
436 436 #-------------------------------------------------------------------------
437 437
438 438 def enable_pylab(self, gui=None, import_all=True):
439 439 """Activate pylab support at runtime.
440 440
441 441 This turns on support for matplotlib, preloads into the interactive
442 442 namespace all of numpy and pylab, and configures IPython to correcdtly
443 443 interact with the GUI event loop. The GUI backend to be used can be
444 444 optionally selected with the optional :param:`gui` argument.
445 445
446 446 Parameters
447 447 ----------
448 448 gui : optional, string
449 449
450 450 If given, dictates the choice of matplotlib GUI backend to use
451 451 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
452 452 'gtk'), otherwise we use the default chosen by matplotlib (as
453 453 dictated by the matplotlib build-time options plus the user's
454 454 matplotlibrc configuration file).
455 455 """
456 456 # We want to prevent the loading of pylab to pollute the user's
457 457 # namespace as shown by the %who* magics, so we execute the activation
458 458 # code in an empty namespace, and we update *both* user_ns and
459 459 # user_ns_hidden with this information.
460 460 ns = {}
461 gui = pylab_activate(ns, gui, import_all)
461 try:
462 gui = pylab_activate(ns, gui, import_all)
463 except KeyError:
464 error("Backend %r not supported" % gui)
465 return
462 466 self.user_ns.update(ns)
463 467 self.user_ns_hidden.update(ns)
464 468 # Now we must activate the gui pylab wants to use, and fix %run to take
465 469 # plot updates into account
466 470 enable_gui(gui)
467 471 self.magic_run = self._pylab_magic_run
468 472
469 473 #-------------------------------------------------------------------------
470 474 # Things related to exiting
471 475 #-------------------------------------------------------------------------
472 476
473 477 def ask_exit(self):
474 478 """ Ask the shell to exit. Can be overiden and used as a callback. """
475 479 self.exit_now = True
476 480
477 481 def exit(self):
478 482 """Handle interactive exit.
479 483
480 484 This method calls the ask_exit callback."""
481 485 if self.confirm_exit:
482 486 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
483 487 self.ask_exit()
484 488 else:
485 489 self.ask_exit()
486 490
487 491 #------------------------------------------------------------------------
488 492 # Magic overrides
489 493 #------------------------------------------------------------------------
490 494 # Once the base class stops inheriting from magic, this code needs to be
491 495 # moved into a separate machinery as well. For now, at least isolate here
492 496 # the magics which this class needs to implement differently from the base
493 497 # class, or that are unique to it.
494 498
495 499 def magic_autoindent(self, parameter_s = ''):
496 500 """Toggle autoindent on/off (if available)."""
497 501
498 502 self.shell.set_autoindent()
499 503 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
500 504
501 505 @skip_doctest
502 506 def magic_cpaste(self, parameter_s=''):
503 507 """Paste & execute a pre-formatted code block from clipboard.
504 508
505 509 You must terminate the block with '--' (two minus-signs) or Ctrl-D alone on the
506 510 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
507 511 is the new sentinel for this operation)
508 512
509 513 The block is dedented prior to execution to enable execution of method
510 514 definitions. '>' and '+' characters at the beginning of a line are
511 515 ignored, to allow pasting directly from e-mails, diff files and
512 516 doctests (the '...' continuation prompt is also stripped). The
513 517 executed block is also assigned to variable named 'pasted_block' for
514 518 later editing with '%edit pasted_block'.
515 519
516 520 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
517 521 This assigns the pasted block to variable 'foo' as string, without
518 522 dedenting or executing it (preceding >>> and + is still stripped)
519 523
520 524 '%cpaste -r' re-executes the block previously entered by cpaste.
521 525
522 526 Do not be alarmed by garbled output on Windows (it's a readline bug).
523 527 Just press enter and type -- (and press enter again) and the block
524 528 will be what was just pasted.
525 529
526 530 IPython statements (magics, shell escapes) are not supported (yet).
527 531
528 532 See also
529 533 --------
530 534 paste: automatically pull code from clipboard.
531 535
532 536 Examples
533 537 --------
534 538 ::
535 539
536 540 In [8]: %cpaste
537 541 Pasting code; enter '--' alone on the line to stop.
538 542 :>>> a = ["world!", "Hello"]
539 543 :>>> print " ".join(sorted(a))
540 544 :--
541 545 Hello world!
542 546 """
543 547
544 548 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
545 549 par = args.strip()
546 550 if opts.has_key('r'):
547 551 self._rerun_pasted()
548 552 return
549 553
550 554 sentinel = opts.get('s','--')
551 555
552 556 block = self._strip_pasted_lines_for_code(
553 557 self._get_pasted_lines(sentinel))
554 558
555 559 self._execute_block(block, par)
556 560
557 561 def magic_paste(self, parameter_s=''):
558 562 """Paste & execute a pre-formatted code block from clipboard.
559 563
560 564 The text is pulled directly from the clipboard without user
561 565 intervention and printed back on the screen before execution (unless
562 566 the -q flag is given to force quiet mode).
563 567
564 568 The block is dedented prior to execution to enable execution of method
565 569 definitions. '>' and '+' characters at the beginning of a line are
566 570 ignored, to allow pasting directly from e-mails, diff files and
567 571 doctests (the '...' continuation prompt is also stripped). The
568 572 executed block is also assigned to variable named 'pasted_block' for
569 573 later editing with '%edit pasted_block'.
570 574
571 575 You can also pass a variable name as an argument, e.g. '%paste foo'.
572 576 This assigns the pasted block to variable 'foo' as string, without
573 577 dedenting or executing it (preceding >>> and + is still stripped)
574 578
575 579 Options
576 580 -------
577 581
578 582 -r: re-executes the block previously entered by cpaste.
579 583
580 584 -q: quiet mode: do not echo the pasted text back to the terminal.
581 585
582 586 IPython statements (magics, shell escapes) are not supported (yet).
583 587
584 588 See also
585 589 --------
586 590 cpaste: manually paste code into terminal until you mark its end.
587 591 """
588 592 opts,args = self.parse_options(parameter_s,'rq',mode='string')
589 593 par = args.strip()
590 594 if opts.has_key('r'):
591 595 self._rerun_pasted()
592 596 return
593 597
594 598 text = self.shell.hooks.clipboard_get()
595 599 block = self._strip_pasted_lines_for_code(text.splitlines())
596 600
597 601 # By default, echo back to terminal unless quiet mode is requested
598 602 if not opts.has_key('q'):
599 603 write = self.shell.write
600 604 write(self.shell.pycolorize(block))
601 605 if not block.endswith('\n'):
602 606 write('\n')
603 607 write("## -- End pasted text --\n")
604 608
605 609 self._execute_block(block, par)
606 610
607 611 def showindentationerror(self):
608 612 super(TerminalInteractiveShell, self).showindentationerror()
609 613 print("If you want to paste code into IPython, try the %paste magic function.")
610 614
611 615
612 616 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,322 +1,322 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities.
3 3
4 4 Authors
5 5 -------
6 6
7 7 * Fernando Perez.
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2009 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 from io import BytesIO
23 23
24 24 from IPython.utils.decorators import flag_calls
25 25
26 26 # If user specifies a GUI, that dictates the backend, otherwise we read the
27 27 # user's mpl default from the mpl rc structure
28 28 backends = {'tk': 'TkAgg',
29 29 'gtk': 'GTKAgg',
30 30 'wx': 'WXAgg',
31 31 'qt': 'Qt4Agg', # qt3 not supported
32 32 'qt4': 'Qt4Agg',
33 33 'osx': 'MacOSX',
34 34 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
35 35
36 36 # We also need a reverse backends2guis mapping that will properly choose which
37 37 # GUI support to activate based on the desired matplotlib backend. For the
38 38 # most part it's just a reverse of the above dict, but we also need to add a
39 39 # few others that map to the same GUI manually:
40 40 backend2gui = dict(zip(backends.values(), backends.keys()))
41 41 # In the reverse mapping, there are a few extra valid matplotlib backends that
42 42 # map to the same GUI support
43 43 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
44 44 backend2gui['WX'] = 'wx'
45 45 backend2gui['CocoaAgg'] = 'osx'
46 46
47 47 #-----------------------------------------------------------------------------
48 48 # Matplotlib utilities
49 49 #-----------------------------------------------------------------------------
50 50
51 51
52 52 def getfigs(*fig_nums):
53 53 """Get a list of matplotlib figures by figure numbers.
54 54
55 55 If no arguments are given, all available figures are returned. If the
56 56 argument list contains references to invalid figures, a warning is printed
57 57 but the function continues pasting further figures.
58 58
59 59 Parameters
60 60 ----------
61 61 figs : tuple
62 62 A tuple of ints giving the figure numbers of the figures to return.
63 63 """
64 64 from matplotlib._pylab_helpers import Gcf
65 65 if not fig_nums:
66 66 fig_managers = Gcf.get_all_fig_managers()
67 67 return [fm.canvas.figure for fm in fig_managers]
68 68 else:
69 69 figs = []
70 70 for num in fig_nums:
71 71 f = Gcf.figs.get(num)
72 72 if f is None:
73 73 print('Warning: figure %s not available.' % num)
74 74 else:
75 75 figs.append(f.canvas.figure)
76 76 return figs
77 77
78 78
79 79 def figsize(sizex, sizey):
80 80 """Set the default figure size to be [sizex, sizey].
81 81
82 82 This is just an easy to remember, convenience wrapper that sets::
83 83
84 84 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
85 85 """
86 86 import matplotlib
87 87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
88 88
89 89
90 90 def print_figure(fig, fmt='png'):
91 91 """Convert a figure to svg or png for inline display."""
92 92 # When there's an empty figure, we shouldn't return anything, otherwise we
93 93 # get big blank areas in the qt console.
94 94 if not fig.axes:
95 95 return
96 96
97 97 fc = fig.get_facecolor()
98 98 ec = fig.get_edgecolor()
99 99 fig.set_facecolor('white')
100 100 fig.set_edgecolor('white')
101 101 try:
102 102 bytes_io = BytesIO()
103 103 # use 72 dpi to match QTConsole's dpi
104 104 fig.canvas.print_figure(bytes_io, format=fmt, dpi=72,
105 105 bbox_inches='tight')
106 106 data = bytes_io.getvalue()
107 107 finally:
108 108 fig.set_facecolor(fc)
109 109 fig.set_edgecolor(ec)
110 110 return data
111 111
112 112
113 113 # We need a little factory function here to create the closure where
114 114 # safe_execfile can live.
115 115 def mpl_runner(safe_execfile):
116 116 """Factory to return a matplotlib-enabled runner for %run.
117 117
118 118 Parameters
119 119 ----------
120 120 safe_execfile : function
121 121 This must be a function with the same interface as the
122 122 :meth:`safe_execfile` method of IPython.
123 123
124 124 Returns
125 125 -------
126 126 A function suitable for use as the ``runner`` argument of the %run magic
127 127 function.
128 128 """
129 129
130 130 def mpl_execfile(fname,*where,**kw):
131 131 """matplotlib-aware wrapper around safe_execfile.
132 132
133 133 Its interface is identical to that of the :func:`execfile` builtin.
134 134
135 135 This is ultimately a call to execfile(), but wrapped in safeties to
136 136 properly handle interactive rendering."""
137 137
138 138 import matplotlib
139 139 import matplotlib.pylab as pylab
140 140
141 141 #print '*** Matplotlib runner ***' # dbg
142 142 # turn off rendering until end of script
143 143 is_interactive = matplotlib.rcParams['interactive']
144 144 matplotlib.interactive(False)
145 145 safe_execfile(fname,*where,**kw)
146 146 matplotlib.interactive(is_interactive)
147 147 # make rendering call now, if the user tried to do it
148 148 if pylab.draw_if_interactive.called:
149 149 pylab.draw()
150 150 pylab.draw_if_interactive.called = False
151 151
152 152 return mpl_execfile
153 153
154 154
155 155 def select_figure_format(shell, fmt):
156 156 """Select figure format for inline backend, either 'png' or 'svg'.
157 157
158 158 Using this method ensures only one figure format is active at a time.
159 159 """
160 160 from matplotlib.figure import Figure
161 161 from IPython.zmq.pylab import backend_inline
162 162
163 163 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
164 164 png_formatter = shell.display_formatter.formatters['image/png']
165 165
166 166 if fmt=='png':
167 167 svg_formatter.type_printers.pop(Figure, None)
168 168 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
169 169 elif fmt=='svg':
170 170 png_formatter.type_printers.pop(Figure, None)
171 171 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
172 172 else:
173 173 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
174 174
175 175 # set the format to be used in the backend()
176 176 backend_inline._figure_format = fmt
177 177
178 178 #-----------------------------------------------------------------------------
179 179 # Code for initializing matplotlib and importing pylab
180 180 #-----------------------------------------------------------------------------
181 181
182 182
183 183 def find_gui_and_backend(gui=None):
184 184 """Given a gui string return the gui and mpl backend.
185 185
186 186 Parameters
187 187 ----------
188 188 gui : str
189 189 Can be one of ('tk','gtk','wx','qt','qt4','inline').
190 190
191 191 Returns
192 192 -------
193 193 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
194 194 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
195 195 """
196 196
197 197 import matplotlib
198 198
199 if gui:
199 if gui and gui != 'auto':
200 200 # select backend based on requested gui
201 201 backend = backends[gui]
202 202 else:
203 203 backend = matplotlib.rcParams['backend']
204 204 # In this case, we need to find what the appropriate gui selection call
205 205 # should be for IPython, so we can activate inputhook accordingly
206 206 gui = backend2gui.get(backend, None)
207 207 return gui, backend
208 208
209 209
210 210 def activate_matplotlib(backend):
211 211 """Activate the given backend and set interactive to True."""
212 212
213 213 import matplotlib
214 214 if backend.startswith('module://'):
215 215 # Work around bug in matplotlib: matplotlib.use converts the
216 216 # backend_id to lowercase even if a module name is specified!
217 217 matplotlib.rcParams['backend'] = backend
218 218 else:
219 219 matplotlib.use(backend)
220 220 matplotlib.interactive(True)
221 221
222 222 # This must be imported last in the matplotlib series, after
223 223 # backend/interactivity choices have been made
224 224 import matplotlib.pylab as pylab
225 225
226 226 # XXX For now leave this commented out, but depending on discussions with
227 227 # mpl-dev, we may be able to allow interactive switching...
228 228 #import matplotlib.pyplot
229 229 #matplotlib.pyplot.switch_backend(backend)
230 230
231 231 pylab.show._needmain = False
232 232 # We need to detect at runtime whether show() is called by the user.
233 233 # For this, we wrap it into a decorator which adds a 'called' flag.
234 234 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
235 235
236 236 def import_pylab(user_ns, backend, import_all=True, shell=None):
237 237 """Import the standard pylab symbols into user_ns."""
238 238
239 239 # Import numpy as np/pyplot as plt are conventions we're trying to
240 240 # somewhat standardize on. Making them available to users by default
241 241 # will greatly help this.
242 242 s = ("import numpy\n"
243 243 "import matplotlib\n"
244 244 "from matplotlib import pylab, mlab, pyplot\n"
245 245 "np = numpy\n"
246 246 "plt = pyplot\n"
247 247 )
248 248 exec s in user_ns
249 249
250 250 if shell is not None:
251 251 exec s in shell.user_ns_hidden
252 252 # If using our svg payload backend, register the post-execution
253 253 # function that will pick up the results for display. This can only be
254 254 # done with access to the real shell object.
255 255 #
256 256 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
257 257
258 258 cfg = InlineBackendConfig.instance(config=shell.config)
259 259 cfg.shell = shell
260 260
261 261 if backend == backends['inline']:
262 262 from IPython.zmq.pylab.backend_inline import flush_figures
263 263 from matplotlib import pyplot
264 264 shell.register_post_execute(flush_figures)
265 265 # load inline_rc
266 266 pyplot.rcParams.update(cfg.rc)
267 267
268 268 # Add 'figsize' to pyplot and to the user's namespace
269 269 user_ns['figsize'] = pyplot.figsize = figsize
270 270 shell.user_ns_hidden['figsize'] = figsize
271 271
272 272 # Setup the default figure format
273 273 fmt = cfg.figure_format
274 274 select_figure_format(shell, fmt)
275 275
276 276 # The old pastefig function has been replaced by display
277 277 from IPython.core.display import display
278 278 # Add display and display_png to the user's namespace
279 279 user_ns['display'] = display
280 280 shell.user_ns_hidden['display'] = display
281 281 user_ns['getfigs'] = getfigs
282 282 shell.user_ns_hidden['getfigs'] = getfigs
283 283
284 284 if import_all:
285 285 s = ("from matplotlib.pylab import *\n"
286 286 "from numpy import *\n")
287 287 exec s in user_ns
288 288 if shell is not None:
289 289 exec s in shell.user_ns_hidden
290 290
291 291
292 292 def pylab_activate(user_ns, gui=None, import_all=True, shell=None):
293 293 """Activate pylab mode in the user's namespace.
294 294
295 295 Loads and initializes numpy, matplotlib and friends for interactive use.
296 296
297 297 Parameters
298 298 ----------
299 299 user_ns : dict
300 300 Namespace where the imports will occur.
301 301
302 302 gui : optional, string
303 303 A valid gui name following the conventions of the %gui magic.
304 304
305 305 import_all : optional, boolean
306 306 If true, an 'import *' is done from numpy and pylab.
307 307
308 308 Returns
309 309 -------
310 310 The actual gui used (if not given as input, it was obtained from matplotlib
311 311 itself, and will be needed next to configure IPython's gui integration.
312 312 """
313 313 gui, backend = find_gui_and_backend(gui)
314 314 activate_matplotlib(backend)
315 315 import_pylab(user_ns, backend, import_all, shell)
316 316
317 317 print """
318 318 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
319 319 For more information, type 'help(pylab)'.""" % backend
320 320
321 321 return gui
322 322
@@ -1,790 +1,789 b''
1 1 #!/usr/bin/env python
2 2 """A simple interactive kernel that talks to a frontend over 0MQ.
3 3
4 4 Things to do:
5 5
6 6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 7 call set_parent on all the PUB objects with the message about to be executed.
8 8 * Implement random port and security key logic.
9 9 * Implement control messages.
10 10 * Implement event loop and poll version.
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Standard library imports.
19 19 import __builtin__
20 20 import atexit
21 21 import sys
22 22 import time
23 23 import traceback
24 24 import logging
25 25
26 26 # System library imports.
27 27 import zmq
28 28
29 29 # Local imports.
30 30 from IPython.config.configurable import Configurable
31 31 from IPython.config.application import boolean_flag
32 32 from IPython.core.application import ProfileDir
33 33 from IPython.core.error import StdinNotImplementedError
34 34 from IPython.core.shellapp import (
35 35 InteractiveShellApp, shell_flags, shell_aliases
36 36 )
37 37 from IPython.utils import io
38 38 from IPython.utils import py3compat
39 39 from IPython.utils.jsonutil import json_clean
40 40 from IPython.lib import pylabtools
41 41 from IPython.utils.traitlets import (
42 42 Any, List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum
43 43 )
44 44
45 45 from entry_point import base_launch_kernel
46 46 from kernelapp import KernelApp, kernel_flags, kernel_aliases
47 47 from iostream import OutStream
48 48 from session import Session, Message
49 49 from zmqshell import ZMQInteractiveShell
50 50
51 51
52 52 #-----------------------------------------------------------------------------
53 53 # Main kernel class
54 54 #-----------------------------------------------------------------------------
55 55
56 56 class Kernel(Configurable):
57 57
58 58 #---------------------------------------------------------------------------
59 59 # Kernel interface
60 60 #---------------------------------------------------------------------------
61 61
62 62 # attribute to override with a GUI
63 63 eventloop = Any(None)
64 64
65 65 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
66 66 session = Instance(Session)
67 67 shell_socket = Instance('zmq.Socket')
68 68 iopub_socket = Instance('zmq.Socket')
69 69 stdin_socket = Instance('zmq.Socket')
70 70 log = Instance(logging.Logger)
71 71
72 72 # Private interface
73 73
74 74 # Time to sleep after flushing the stdout/err buffers in each execute
75 75 # cycle. While this introduces a hard limit on the minimal latency of the
76 76 # execute cycle, it helps prevent output synchronization problems for
77 77 # clients.
78 78 # Units are in seconds. The minimum zmq latency on local host is probably
79 79 # ~150 microseconds, set this to 500us for now. We may need to increase it
80 80 # a little if it's not enough after more interactive testing.
81 81 _execute_sleep = Float(0.0005, config=True)
82 82
83 83 # Frequency of the kernel's event loop.
84 84 # Units are in seconds, kernel subclasses for GUI toolkits may need to
85 85 # adapt to milliseconds.
86 86 _poll_interval = Float(0.05, config=True)
87 87
88 88 # If the shutdown was requested over the network, we leave here the
89 89 # necessary reply message so it can be sent by our registered atexit
90 90 # handler. This ensures that the reply is only sent to clients truly at
91 91 # the end of our shutdown process (which happens after the underlying
92 92 # IPython shell's own shutdown).
93 93 _shutdown_message = None
94 94
95 95 # This is a dict of port number that the kernel is listening on. It is set
96 96 # by record_ports and used by connect_request.
97 97 _recorded_ports = Dict()
98 98
99 99
100 100
101 101 def __init__(self, **kwargs):
102 102 super(Kernel, self).__init__(**kwargs)
103 103
104 104 # Before we even start up the shell, register *first* our exit handlers
105 105 # so they come before the shell's
106 106 atexit.register(self._at_shutdown)
107 107
108 108 # Initialize the InteractiveShell subclass
109 109 self.shell = ZMQInteractiveShell.instance(config=self.config)
110 110 self.shell.displayhook.session = self.session
111 111 self.shell.displayhook.pub_socket = self.iopub_socket
112 112 self.shell.display_pub.session = self.session
113 113 self.shell.display_pub.pub_socket = self.iopub_socket
114 114
115 115 # TMP - hack while developing
116 116 self.shell._reply_content = None
117 117
118 118 # Build dict of handlers for message types
119 119 msg_types = [ 'execute_request', 'complete_request',
120 120 'object_info_request', 'history_request',
121 121 'connect_request', 'shutdown_request']
122 122 self.handlers = {}
123 123 for msg_type in msg_types:
124 124 self.handlers[msg_type] = getattr(self, msg_type)
125 125
126 126 def do_one_iteration(self):
127 127 """Do one iteration of the kernel's evaluation loop.
128 128 """
129 129 try:
130 130 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
131 131 except Exception:
132 132 self.log.warn("Invalid Message:", exc_info=True)
133 133 return
134 134 if msg is None:
135 135 return
136 136
137 137 msg_type = msg['header']['msg_type']
138 138
139 139 # This assert will raise in versions of zeromq 2.0.7 and lesser.
140 140 # We now require 2.0.8 or above, so we can uncomment for safety.
141 141 # print(ident,msg, file=sys.__stdout__)
142 142 assert ident is not None, "Missing message part."
143 143
144 144 # Print some info about this message and leave a '--->' marker, so it's
145 145 # easier to trace visually the message chain when debugging. Each
146 146 # handler prints its message at the end.
147 147 self.log.debug('\n*** MESSAGE TYPE:'+str(msg_type)+'***')
148 148 self.log.debug(' Content: '+str(msg['content'])+'\n --->\n ')
149 149
150 150 # Find and call actual handler for message
151 151 handler = self.handlers.get(msg_type, None)
152 152 if handler is None:
153 153 self.log.error("UNKNOWN MESSAGE TYPE:" +str(msg))
154 154 else:
155 155 handler(ident, msg)
156 156
157 157 # Check whether we should exit, in case the incoming message set the
158 158 # exit flag on
159 159 if self.shell.exit_now:
160 160 self.log.debug('\nExiting IPython kernel...')
161 161 # We do a normal, clean exit, which allows any actions registered
162 162 # via atexit (such as history saving) to take place.
163 163 sys.exit(0)
164 164
165 165
166 166 def start(self):
167 167 """ Start the kernel main loop.
168 168 """
169 169 poller = zmq.Poller()
170 170 poller.register(self.shell_socket, zmq.POLLIN)
171 171 # loop while self.eventloop has not been overridden
172 172 while self.eventloop is None:
173 173 try:
174 174 # scale by extra factor of 10, because there is no
175 175 # reason for this to be anything less than ~ 0.1s
176 176 # since it is a real poller and will respond
177 177 # to events immediately
178 178
179 179 # double nested try/except, to properly catch KeyboardInterrupt
180 180 # due to pyzmq Issue #130
181 181 try:
182 182 poller.poll(10*1000*self._poll_interval)
183 183 self.do_one_iteration()
184 184 except:
185 185 raise
186 186 except KeyboardInterrupt:
187 187 # Ctrl-C shouldn't crash the kernel
188 188 io.raw_print("KeyboardInterrupt caught in kernel")
189 189 if self.eventloop is not None:
190 190 try:
191 191 self.eventloop(self)
192 192 except KeyboardInterrupt:
193 193 # Ctrl-C shouldn't crash the kernel
194 194 io.raw_print("KeyboardInterrupt caught in kernel")
195 195
196 196
197 197 def record_ports(self, ports):
198 198 """Record the ports that this kernel is using.
199 199
200 200 The creator of the Kernel instance must call this methods if they
201 201 want the :meth:`connect_request` method to return the port numbers.
202 202 """
203 203 self._recorded_ports = ports
204 204
205 205 #---------------------------------------------------------------------------
206 206 # Kernel request handlers
207 207 #---------------------------------------------------------------------------
208 208
209 209 def _publish_pyin(self, code, parent):
210 210 """Publish the code request on the pyin stream."""
211 211
212 212 pyin_msg = self.session.send(self.iopub_socket, u'pyin',{u'code':code}, parent=parent)
213 213
214 214 def execute_request(self, ident, parent):
215 215
216 216 status_msg = self.session.send(self.iopub_socket,
217 217 u'status',
218 218 {u'execution_state':u'busy'},
219 219 parent=parent
220 220 )
221 221
222 222 try:
223 223 content = parent[u'content']
224 224 code = content[u'code']
225 225 silent = content[u'silent']
226 226 except:
227 227 self.log.error("Got bad msg: ")
228 228 self.log.error(str(Message(parent)))
229 229 return
230 230
231 231 shell = self.shell # we'll need this a lot here
232 232
233 233 # Replace raw_input. Note that is not sufficient to replace
234 234 # raw_input in the user namespace.
235 235 if content.get('allow_stdin', False):
236 236 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
237 237 else:
238 238 raw_input = lambda prompt='' : self._no_raw_input()
239 239
240 240 if py3compat.PY3:
241 241 __builtin__.input = raw_input
242 242 else:
243 243 __builtin__.raw_input = raw_input
244 244
245 245 # Set the parent message of the display hook and out streams.
246 246 shell.displayhook.set_parent(parent)
247 247 shell.display_pub.set_parent(parent)
248 248 sys.stdout.set_parent(parent)
249 249 sys.stderr.set_parent(parent)
250 250
251 251 # Re-broadcast our input for the benefit of listening clients, and
252 252 # start computing output
253 253 if not silent:
254 254 self._publish_pyin(code, parent)
255 255
256 256 reply_content = {}
257 257 try:
258 258 if silent:
259 259 # run_code uses 'exec' mode, so no displayhook will fire, and it
260 260 # doesn't call logging or history manipulations. Print
261 261 # statements in that code will obviously still execute.
262 262 shell.run_code(code)
263 263 else:
264 264 # FIXME: the shell calls the exception handler itself.
265 265 shell.run_cell(code, store_history=True)
266 266 except:
267 267 status = u'error'
268 268 # FIXME: this code right now isn't being used yet by default,
269 269 # because the run_cell() call above directly fires off exception
270 270 # reporting. This code, therefore, is only active in the scenario
271 271 # where runlines itself has an unhandled exception. We need to
272 272 # uniformize this, for all exception construction to come from a
273 273 # single location in the codbase.
274 274 etype, evalue, tb = sys.exc_info()
275 275 tb_list = traceback.format_exception(etype, evalue, tb)
276 276 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
277 277 else:
278 278 status = u'ok'
279 279
280 280 reply_content[u'status'] = status
281 281
282 282 # Return the execution counter so clients can display prompts
283 283 reply_content['execution_count'] = shell.execution_count -1
284 284
285 285 # FIXME - fish exception info out of shell, possibly left there by
286 286 # runlines. We'll need to clean up this logic later.
287 287 if shell._reply_content is not None:
288 288 reply_content.update(shell._reply_content)
289 289 # reset after use
290 290 shell._reply_content = None
291 291
292 292 # At this point, we can tell whether the main code execution succeeded
293 293 # or not. If it did, we proceed to evaluate user_variables/expressions
294 294 if reply_content['status'] == 'ok':
295 295 reply_content[u'user_variables'] = \
296 296 shell.user_variables(content[u'user_variables'])
297 297 reply_content[u'user_expressions'] = \
298 298 shell.user_expressions(content[u'user_expressions'])
299 299 else:
300 300 # If there was an error, don't even try to compute variables or
301 301 # expressions
302 302 reply_content[u'user_variables'] = {}
303 303 reply_content[u'user_expressions'] = {}
304 304
305 305 # Payloads should be retrieved regardless of outcome, so we can both
306 306 # recover partial output (that could have been generated early in a
307 307 # block, before an error) and clear the payload system always.
308 308 reply_content[u'payload'] = shell.payload_manager.read_payload()
309 309 # Be agressive about clearing the payload because we don't want
310 310 # it to sit in memory until the next execute_request comes in.
311 311 shell.payload_manager.clear_payload()
312 312
313 313 # Flush output before sending the reply.
314 314 sys.stdout.flush()
315 315 sys.stderr.flush()
316 316 # FIXME: on rare occasions, the flush doesn't seem to make it to the
317 317 # clients... This seems to mitigate the problem, but we definitely need
318 318 # to better understand what's going on.
319 319 if self._execute_sleep:
320 320 time.sleep(self._execute_sleep)
321 321
322 322 # Send the reply.
323 323 reply_content = json_clean(reply_content)
324 324 reply_msg = self.session.send(self.shell_socket, u'execute_reply',
325 325 reply_content, parent, ident=ident)
326 326 self.log.debug(str(reply_msg))
327 327
328 328 if reply_msg['content']['status'] == u'error':
329 329 self._abort_queue()
330 330
331 331 status_msg = self.session.send(self.iopub_socket,
332 332 u'status',
333 333 {u'execution_state':u'idle'},
334 334 parent=parent
335 335 )
336 336
337 337 def complete_request(self, ident, parent):
338 338 txt, matches = self._complete(parent)
339 339 matches = {'matches' : matches,
340 340 'matched_text' : txt,
341 341 'status' : 'ok'}
342 342 matches = json_clean(matches)
343 343 completion_msg = self.session.send(self.shell_socket, 'complete_reply',
344 344 matches, parent, ident)
345 345 self.log.debug(str(completion_msg))
346 346
347 347 def object_info_request(self, ident, parent):
348 348 object_info = self.shell.object_inspect(parent['content']['oname'])
349 349 # Before we send this object over, we scrub it for JSON usage
350 350 oinfo = json_clean(object_info)
351 351 msg = self.session.send(self.shell_socket, 'object_info_reply',
352 352 oinfo, parent, ident)
353 353 self.log.debug(msg)
354 354
355 355 def history_request(self, ident, parent):
356 356 # We need to pull these out, as passing **kwargs doesn't work with
357 357 # unicode keys before Python 2.6.5.
358 358 hist_access_type = parent['content']['hist_access_type']
359 359 raw = parent['content']['raw']
360 360 output = parent['content']['output']
361 361 if hist_access_type == 'tail':
362 362 n = parent['content']['n']
363 363 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
364 364 include_latest=True)
365 365
366 366 elif hist_access_type == 'range':
367 367 session = parent['content']['session']
368 368 start = parent['content']['start']
369 369 stop = parent['content']['stop']
370 370 hist = self.shell.history_manager.get_range(session, start, stop,
371 371 raw=raw, output=output)
372 372
373 373 elif hist_access_type == 'search':
374 374 pattern = parent['content']['pattern']
375 375 hist = self.shell.history_manager.search(pattern, raw=raw, output=output)
376 376
377 377 else:
378 378 hist = []
379 379 content = {'history' : list(hist)}
380 380 content = json_clean(content)
381 381 msg = self.session.send(self.shell_socket, 'history_reply',
382 382 content, parent, ident)
383 383 self.log.debug(str(msg))
384 384
385 385 def connect_request(self, ident, parent):
386 386 if self._recorded_ports is not None:
387 387 content = self._recorded_ports.copy()
388 388 else:
389 389 content = {}
390 390 msg = self.session.send(self.shell_socket, 'connect_reply',
391 391 content, parent, ident)
392 392 self.log.debug(msg)
393 393
394 394 def shutdown_request(self, ident, parent):
395 395 self.shell.exit_now = True
396 396 self._shutdown_message = self.session.msg(u'shutdown_reply', parent['content'], parent)
397 397 sys.exit(0)
398 398
399 399 #---------------------------------------------------------------------------
400 400 # Protected interface
401 401 #---------------------------------------------------------------------------
402 402
403 403 def _abort_queue(self):
404 404 while True:
405 405 try:
406 406 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
407 407 except Exception:
408 408 self.log.warn("Invalid Message:", exc_info=True)
409 409 continue
410 410 if msg is None:
411 411 break
412 412 else:
413 413 assert ident is not None, \
414 414 "Unexpected missing message part."
415 415
416 416 self.log.debug("Aborting:\n"+str(Message(msg)))
417 417 msg_type = msg['header']['msg_type']
418 418 reply_type = msg_type.split('_')[0] + '_reply'
419 419 reply_msg = self.session.send(self.shell_socket, reply_type,
420 420 {'status' : 'aborted'}, msg, ident=ident)
421 421 self.log.debug(reply_msg)
422 422 # We need to wait a bit for requests to come in. This can probably
423 423 # be set shorter for true asynchronous clients.
424 424 time.sleep(0.1)
425 425
426 426 def _no_raw_input(self):
427 427 """Raise StdinNotImplentedError if active frontend doesn't support stdin."""
428 428 raise StdinNotImplementedError("raw_input was called, but this frontend does not support stdin.")
429 429
430 430 def _raw_input(self, prompt, ident, parent):
431 431 # Flush output before making the request.
432 432 sys.stderr.flush()
433 433 sys.stdout.flush()
434 434
435 435 # Send the input request.
436 436 content = json_clean(dict(prompt=prompt))
437 437 msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident)
438 438
439 439 # Await a response.
440 440 while True:
441 441 try:
442 442 ident, reply = self.session.recv(self.stdin_socket, 0)
443 443 except Exception:
444 444 self.log.warn("Invalid Message:", exc_info=True)
445 445 else:
446 446 break
447 447 try:
448 448 value = reply['content']['value']
449 449 except:
450 450 self.log.error("Got bad raw_input reply: ")
451 451 self.log.error(str(Message(parent)))
452 452 value = ''
453 453 return value
454 454
455 455 def _complete(self, msg):
456 456 c = msg['content']
457 457 try:
458 458 cpos = int(c['cursor_pos'])
459 459 except:
460 460 # If we don't get something that we can convert to an integer, at
461 461 # least attempt the completion guessing the cursor is at the end of
462 462 # the text, if there's any, and otherwise of the line
463 463 cpos = len(c['text'])
464 464 if cpos==0:
465 465 cpos = len(c['line'])
466 466 return self.shell.complete(c['text'], c['line'], cpos)
467 467
468 468 def _object_info(self, context):
469 469 symbol, leftover = self._symbol_from_context(context)
470 470 if symbol is not None and not leftover:
471 471 doc = getattr(symbol, '__doc__', '')
472 472 else:
473 473 doc = ''
474 474 object_info = dict(docstring = doc)
475 475 return object_info
476 476
477 477 def _symbol_from_context(self, context):
478 478 if not context:
479 479 return None, context
480 480
481 481 base_symbol_string = context[0]
482 482 symbol = self.shell.user_ns.get(base_symbol_string, None)
483 483 if symbol is None:
484 484 symbol = __builtin__.__dict__.get(base_symbol_string, None)
485 485 if symbol is None:
486 486 return None, context
487 487
488 488 context = context[1:]
489 489 for i, name in enumerate(context):
490 490 new_symbol = getattr(symbol, name, None)
491 491 if new_symbol is None:
492 492 return symbol, context[i:]
493 493 else:
494 494 symbol = new_symbol
495 495
496 496 return symbol, []
497 497
498 498 def _at_shutdown(self):
499 499 """Actions taken at shutdown by the kernel, called by python's atexit.
500 500 """
501 501 # io.rprint("Kernel at_shutdown") # dbg
502 502 if self._shutdown_message is not None:
503 503 self.session.send(self.shell_socket, self._shutdown_message)
504 504 self.session.send(self.iopub_socket, self._shutdown_message)
505 505 self.log.debug(str(self._shutdown_message))
506 506 # A very short sleep to give zmq time to flush its message buffers
507 507 # before Python truly shuts down.
508 508 time.sleep(0.01)
509 509
510 510
511 511 #------------------------------------------------------------------------------
512 512 # Eventloops for integrating the Kernel into different GUIs
513 513 #------------------------------------------------------------------------------
514 514
515 515
516 516 def loop_qt4(kernel):
517 517 """Start a kernel with PyQt4 event loop integration."""
518 518
519 519 from IPython.external.qt_for_kernel import QtCore
520 520 from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4
521 521
522 522 kernel.app = get_app_qt4([" "])
523 523 kernel.app.setQuitOnLastWindowClosed(False)
524 524 kernel.timer = QtCore.QTimer()
525 525 kernel.timer.timeout.connect(kernel.do_one_iteration)
526 526 # Units for the timer are in milliseconds
527 527 kernel.timer.start(1000*kernel._poll_interval)
528 528 start_event_loop_qt4(kernel.app)
529 529
530 530
531 531 def loop_wx(kernel):
532 532 """Start a kernel with wx event loop support."""
533 533
534 534 import wx
535 535 from IPython.lib.guisupport import start_event_loop_wx
536 536
537 537 doi = kernel.do_one_iteration
538 538 # Wx uses milliseconds
539 539 poll_interval = int(1000*kernel._poll_interval)
540 540
541 541 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
542 542 # We make the Frame hidden when we create it in the main app below.
543 543 class TimerFrame(wx.Frame):
544 544 def __init__(self, func):
545 545 wx.Frame.__init__(self, None, -1)
546 546 self.timer = wx.Timer(self)
547 547 # Units for the timer are in milliseconds
548 548 self.timer.Start(poll_interval)
549 549 self.Bind(wx.EVT_TIMER, self.on_timer)
550 550 self.func = func
551 551
552 552 def on_timer(self, event):
553 553 self.func()
554 554
555 555 # We need a custom wx.App to create our Frame subclass that has the
556 556 # wx.Timer to drive the ZMQ event loop.
557 557 class IPWxApp(wx.App):
558 558 def OnInit(self):
559 559 self.frame = TimerFrame(doi)
560 560 self.frame.Show(False)
561 561 return True
562 562
563 563 # The redirect=False here makes sure that wx doesn't replace
564 564 # sys.stdout/stderr with its own classes.
565 565 kernel.app = IPWxApp(redirect=False)
566 566 start_event_loop_wx(kernel.app)
567 567
568 568
569 569 def loop_tk(kernel):
570 570 """Start a kernel with the Tk event loop."""
571 571
572 572 import Tkinter
573 573 doi = kernel.do_one_iteration
574 574 # Tk uses milliseconds
575 575 poll_interval = int(1000*kernel._poll_interval)
576 576 # For Tkinter, we create a Tk object and call its withdraw method.
577 577 class Timer(object):
578 578 def __init__(self, func):
579 579 self.app = Tkinter.Tk()
580 580 self.app.withdraw()
581 581 self.func = func
582 582
583 583 def on_timer(self):
584 584 self.func()
585 585 self.app.after(poll_interval, self.on_timer)
586 586
587 587 def start(self):
588 588 self.on_timer() # Call it once to get things going.
589 589 self.app.mainloop()
590 590
591 591 kernel.timer = Timer(doi)
592 592 kernel.timer.start()
593 593
594 594
595 595 def loop_gtk(kernel):
596 596 """Start the kernel, coordinating with the GTK event loop"""
597 597 from .gui.gtkembed import GTKEmbed
598 598
599 599 gtk_kernel = GTKEmbed(kernel)
600 600 gtk_kernel.start()
601 601
602 602
603 603 def loop_cocoa(kernel):
604 604 """Start the kernel, coordinating with the Cocoa CFRunLoop event loop
605 605 via the matplotlib MacOSX backend.
606 606 """
607 607 import matplotlib
608 608 if matplotlib.__version__ < '1.1.0':
609 609 kernel.log.warn(
610 610 "MacOSX backend in matplotlib %s doesn't have a Timer, "
611 611 "falling back on Tk for CFRunLoop integration. Note that "
612 612 "even this won't work if Tk is linked against X11 instead of "
613 613 "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, "
614 614 "you must use matplotlib >= 1.1.0, or a native libtk."
615 615 )
616 616 return loop_tk(kernel)
617 617
618 618 from matplotlib.backends.backend_macosx import TimerMac, show
619 619
620 620 # scale interval for sec->ms
621 621 poll_interval = int(1000*kernel._poll_interval)
622 622
623 623 real_excepthook = sys.excepthook
624 624 def handle_int(etype, value, tb):
625 625 """don't let KeyboardInterrupts look like crashes"""
626 626 if etype is KeyboardInterrupt:
627 627 io.raw_print("KeyboardInterrupt caught in CFRunLoop")
628 628 else:
629 629 real_excepthook(etype, value, tb)
630 630
631 631 # add doi() as a Timer to the CFRunLoop
632 632 def doi():
633 633 # restore excepthook during IPython code
634 634 sys.excepthook = real_excepthook
635 635 kernel.do_one_iteration()
636 636 # and back:
637 637 sys.excepthook = handle_int
638 638
639 639 t = TimerMac(poll_interval)
640 640 t.add_callback(doi)
641 641 t.start()
642 642
643 643 # but still need a Poller for when there are no active windows,
644 644 # during which time mainloop() returns immediately
645 645 poller = zmq.Poller()
646 646 poller.register(kernel.shell_socket, zmq.POLLIN)
647 647
648 648 while True:
649 649 try:
650 650 # double nested try/except, to properly catch KeyboardInterrupt
651 651 # due to pyzmq Issue #130
652 652 try:
653 653 # don't let interrupts during mainloop invoke crash_handler:
654 654 sys.excepthook = handle_int
655 655 show.mainloop()
656 656 sys.excepthook = real_excepthook
657 657 # use poller if mainloop returned (no windows)
658 658 # scale by extra factor of 10, since it's a real poll
659 659 poller.poll(10*poll_interval)
660 660 kernel.do_one_iteration()
661 661 except:
662 662 raise
663 663 except KeyboardInterrupt:
664 664 # Ctrl-C shouldn't crash the kernel
665 665 io.raw_print("KeyboardInterrupt caught in kernel")
666 666 finally:
667 667 # ensure excepthook is restored
668 668 sys.excepthook = real_excepthook
669 669
670 670 # mapping of keys to loop functions
671 671 loop_map = {
672 672 'qt' : loop_qt4,
673 673 'qt4': loop_qt4,
674 674 'inline': None,
675 675 'osx': loop_cocoa,
676 676 'wx' : loop_wx,
677 677 'tk' : loop_tk,
678 678 'gtk': loop_gtk,
679 679 }
680 680
681 681 def enable_gui(gui, kernel=None):
682 682 """Enable integration with a give GUI"""
683 683 if kernel is None:
684 684 kernel = IPKernelApp.instance().kernel
685 685 if gui not in loop_map:
686 686 raise ValueError("GUI %r not supported" % gui)
687 687 loop = loop_map[gui]
688 688 if kernel.eventloop is not None and kernel.eventloop is not loop:
689 689 raise RuntimeError("Cannot activate multiple GUI eventloops")
690 690 kernel.eventloop = loop
691 691
692 692
693 693 #-----------------------------------------------------------------------------
694 694 # Aliases and Flags for the IPKernelApp
695 695 #-----------------------------------------------------------------------------
696 696
697 697 flags = dict(kernel_flags)
698 698 flags.update(shell_flags)
699 699
700 700 addflag = lambda *args: flags.update(boolean_flag(*args))
701 701
702 702 flags['pylab'] = (
703 703 {'IPKernelApp' : {'pylab' : 'auto'}},
704 704 """Pre-load matplotlib and numpy for interactive use with
705 705 the default matplotlib backend."""
706 706 )
707 707
708 708 aliases = dict(kernel_aliases)
709 709 aliases.update(shell_aliases)
710 710
711 711 # it's possible we don't want short aliases for *all* of these:
712 712 aliases.update(dict(
713 713 pylab='IPKernelApp.pylab',
714 714 ))
715 715
716 716 #-----------------------------------------------------------------------------
717 717 # The IPKernelApp class
718 718 #-----------------------------------------------------------------------------
719 719
720 720 class IPKernelApp(KernelApp, InteractiveShellApp):
721 721 name = 'ipkernel'
722 722
723 723 aliases = Dict(aliases)
724 724 flags = Dict(flags)
725 725 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
726 726 # configurables
727 727 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
728 728 config=True,
729 729 help="""Pre-load matplotlib and numpy for interactive use,
730 730 selecting a particular matplotlib backend and loop integration.
731 731 """
732 732 )
733 733 def initialize(self, argv=None):
734 734 super(IPKernelApp, self).initialize(argv)
735 735 self.init_shell()
736 736 self.init_extensions()
737 737 self.init_code()
738 738
739 739 def init_kernel(self):
740 740 kernel_factory = Kernel
741 741
742 742 if self.pylab:
743 key = None if self.pylab == 'auto' else self.pylab
744 gui, backend = pylabtools.find_gui_and_backend(key)
743 gui, backend = pylabtools.find_gui_and_backend(self.pylab)
745 744
746 745 kernel = kernel_factory(config=self.config, session=self.session,
747 746 shell_socket=self.shell_socket,
748 747 iopub_socket=self.iopub_socket,
749 748 stdin_socket=self.stdin_socket,
750 749 log=self.log,
751 750 )
752 751 self.kernel = kernel
753 752 kernel.record_ports(self.ports)
754 753
755 754 if self.pylab:
756 755 kernel.shell.enable_pylab(gui, import_all=self.pylab_import_all)
757 756
758 757 def init_shell(self):
759 758 self.shell = self.kernel.shell
760 759
761 760
762 761 #-----------------------------------------------------------------------------
763 762 # Kernel main and launch functions
764 763 #-----------------------------------------------------------------------------
765 764
766 765 def launch_kernel(*args, **kwargs):
767 766 """Launches a localhost IPython kernel, binding to the specified ports.
768 767
769 768 This function simply calls entry_point.base_launch_kernel with the right first
770 769 command to start an ipkernel. See base_launch_kernel for arguments.
771 770
772 771 Returns
773 772 -------
774 773 A tuple of form:
775 774 (kernel_process, shell_port, iopub_port, stdin_port, hb_port)
776 775 where kernel_process is a Popen object and the ports are integers.
777 776 """
778 777 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
779 778 *args, **kwargs)
780 779
781 780
782 781 def main():
783 782 """Run an IPKernel as an application"""
784 783 app = IPKernelApp.instance()
785 784 app.initialize()
786 785 app.start()
787 786
788 787
789 788 if __name__ == '__main__':
790 789 main()
@@ -1,548 +1,561 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 19 import inspect
20 20 import os
21 21 import sys
22 22 from subprocess import Popen, PIPE
23 23
24 24 # Our own
25 25 from IPython.core.interactiveshell import (
26 26 InteractiveShell, InteractiveShellABC
27 27 )
28 28 from IPython.core import page
29 29 from IPython.core.autocall import ZMQExitAutocall
30 30 from IPython.core.displaypub import DisplayPublisher
31 31 from IPython.core.macro import Macro
32 32 from IPython.core.magic import MacroToEdit
33 33 from IPython.core.payloadpage import install_payload_page
34 34 from IPython.lib import pylabtools
35 35 from IPython.lib.kernel import (
36 36 get_connection_file, get_connection_info, connect_qtconsole
37 37 )
38 38 from IPython.utils import io
39 39 from IPython.utils.jsonutil import json_clean
40 40 from IPython.utils.path import get_py_filename
41 41 from IPython.utils.process import arg_split
42 42 from IPython.utils.traitlets import Instance, Type, Dict, CBool
43 43 from IPython.utils.warn import warn, error
44 44 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
45 45 from IPython.zmq.session import extract_header
46 46 from session import Session
47 47
48 48 #-----------------------------------------------------------------------------
49 49 # Globals and side-effects
50 50 #-----------------------------------------------------------------------------
51 51
52 52 # Install the payload version of page.
53 53 install_payload_page()
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Functions and classes
57 57 #-----------------------------------------------------------------------------
58 58
59 59 class ZMQDisplayPublisher(DisplayPublisher):
60 60 """A display publisher that publishes data using a ZeroMQ PUB socket."""
61 61
62 62 session = Instance(Session)
63 63 pub_socket = Instance('zmq.Socket')
64 64 parent_header = Dict({})
65 65
66 66 def set_parent(self, parent):
67 67 """Set the parent for outbound messages."""
68 68 self.parent_header = extract_header(parent)
69 69
70 70 def publish(self, source, data, metadata=None):
71 71 if metadata is None:
72 72 metadata = {}
73 73 self._validate_data(source, data, metadata)
74 74 content = {}
75 75 content['source'] = source
76 76 _encode_binary(data)
77 77 content['data'] = data
78 78 content['metadata'] = metadata
79 79 self.session.send(
80 80 self.pub_socket, u'display_data', json_clean(content),
81 81 parent=self.parent_header
82 82 )
83 83
84 84 def clear_output(self, stdout=True, stderr=True, other=True):
85 85 content = dict(stdout=stdout, stderr=stderr, other=other)
86 86 self.session.send(
87 87 self.pub_socket, u'clear_output', content,
88 88 parent=self.parent_header
89 89 )
90 90
91 91 class ZMQInteractiveShell(InteractiveShell):
92 92 """A subclass of InteractiveShell for ZMQ."""
93 93
94 94 displayhook_class = Type(ZMQShellDisplayHook)
95 95 display_pub_class = Type(ZMQDisplayPublisher)
96 96
97 97 # Override the traitlet in the parent class, because there's no point using
98 98 # readline for the kernel. Can be removed when the readline code is moved
99 99 # to the terminal frontend.
100 100 colors_force = CBool(True)
101 101 readline_use = CBool(False)
102 102 # autoindent has no meaning in a zmqshell, and attempting to enable it
103 103 # will print a warning in the absence of readline.
104 104 autoindent = CBool(False)
105 105
106 106 exiter = Instance(ZMQExitAutocall)
107 107 def _exiter_default(self):
108 108 return ZMQExitAutocall(self)
109 109
110 110 keepkernel_on_exit = None
111 111
112 112 def init_environment(self):
113 113 """Configure the user's environment.
114 114
115 115 """
116 116 env = os.environ
117 117 # These two ensure 'ls' produces nice coloring on BSD-derived systems
118 118 env['TERM'] = 'xterm-color'
119 119 env['CLICOLOR'] = '1'
120 120 # Since normal pagers don't work at all (over pexpect we don't have
121 121 # single-key control of the subprocess), try to disable paging in
122 122 # subprocesses as much as possible.
123 123 env['PAGER'] = 'cat'
124 124 env['GIT_PAGER'] = 'cat'
125 125
126 126 def auto_rewrite_input(self, cmd):
127 127 """Called to show the auto-rewritten input for autocall and friends.
128 128
129 129 FIXME: this payload is currently not correctly processed by the
130 130 frontend.
131 131 """
132 132 new = self.displayhook.prompt1.auto_rewrite() + cmd
133 133 payload = dict(
134 134 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
135 135 transformed_input=new,
136 136 )
137 137 self.payload_manager.write_payload(payload)
138 138
139 139 def ask_exit(self):
140 140 """Engage the exit actions."""
141 141 payload = dict(
142 142 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
143 143 exit=True,
144 144 keepkernel=self.keepkernel_on_exit,
145 145 )
146 146 self.payload_manager.write_payload(payload)
147 147
148 148 def _showtraceback(self, etype, evalue, stb):
149 149
150 150 exc_content = {
151 151 u'traceback' : stb,
152 152 u'ename' : unicode(etype.__name__),
153 153 u'evalue' : unicode(evalue)
154 154 }
155 155
156 156 dh = self.displayhook
157 157 # Send exception info over pub socket for other clients than the caller
158 158 # to pick up
159 159 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header)
160 160
161 161 # FIXME - Hack: store exception info in shell object. Right now, the
162 162 # caller is reading this info after the fact, we need to fix this logic
163 163 # to remove this hack. Even uglier, we need to store the error status
164 164 # here, because in the main loop, the logic that sets it is being
165 165 # skipped because runlines swallows the exceptions.
166 166 exc_content[u'status'] = u'error'
167 167 self._reply_content = exc_content
168 168 # /FIXME
169 169
170 170 return exc_content
171 171
172 172 #------------------------------------------------------------------------
173 173 # Magic overrides
174 174 #------------------------------------------------------------------------
175 175 # Once the base class stops inheriting from magic, this code needs to be
176 176 # moved into a separate machinery as well. For now, at least isolate here
177 177 # the magics which this class needs to implement differently from the base
178 178 # class, or that are unique to it.
179 179
180 180 def magic_doctest_mode(self,parameter_s=''):
181 181 """Toggle doctest mode on and off.
182 182
183 183 This mode is intended to make IPython behave as much as possible like a
184 184 plain Python shell, from the perspective of how its prompts, exceptions
185 185 and output look. This makes it easy to copy and paste parts of a
186 186 session into doctests. It does so by:
187 187
188 188 - Changing the prompts to the classic ``>>>`` ones.
189 189 - Changing the exception reporting mode to 'Plain'.
190 190 - Disabling pretty-printing of output.
191 191
192 192 Note that IPython also supports the pasting of code snippets that have
193 193 leading '>>>' and '...' prompts in them. This means that you can paste
194 194 doctests from files or docstrings (even if they have leading
195 195 whitespace), and the code will execute correctly. You can then use
196 196 '%history -t' to see the translated history; this will give you the
197 197 input after removal of all the leading prompts and whitespace, which
198 198 can be pasted back into an editor.
199 199
200 200 With these features, you can switch into this mode easily whenever you
201 201 need to do testing and changes to doctests, without having to leave
202 202 your existing IPython session.
203 203 """
204 204
205 205 from IPython.utils.ipstruct import Struct
206 206
207 207 # Shorthands
208 208 shell = self.shell
209 209 disp_formatter = self.shell.display_formatter
210 210 ptformatter = disp_formatter.formatters['text/plain']
211 211 # dstore is a data store kept in the instance metadata bag to track any
212 212 # changes we make, so we can undo them later.
213 213 dstore = shell.meta.setdefault('doctest_mode', Struct())
214 214 save_dstore = dstore.setdefault
215 215
216 216 # save a few values we'll need to recover later
217 217 mode = save_dstore('mode', False)
218 218 save_dstore('rc_pprint', ptformatter.pprint)
219 219 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
220 220 save_dstore('xmode', shell.InteractiveTB.mode)
221 221
222 222 if mode == False:
223 223 # turn on
224 224 ptformatter.pprint = False
225 225 disp_formatter.plain_text_only = True
226 226 shell.magic_xmode('Plain')
227 227 else:
228 228 # turn off
229 229 ptformatter.pprint = dstore.rc_pprint
230 230 disp_formatter.plain_text_only = dstore.rc_plain_text_only
231 231 shell.magic_xmode(dstore.xmode)
232 232
233 233 # Store new mode and inform on console
234 234 dstore.mode = bool(1-int(mode))
235 235 mode_label = ['OFF','ON'][dstore.mode]
236 236 print('Doctest mode is:', mode_label)
237 237
238 238 # Send the payload back so that clients can modify their prompt display
239 239 payload = dict(
240 240 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
241 241 mode=dstore.mode)
242 242 self.payload_manager.write_payload(payload)
243 243
244 244 def magic_edit(self,parameter_s='',last_call=['','']):
245 245 """Bring up an editor and execute the resulting code.
246 246
247 247 Usage:
248 248 %edit [options] [args]
249 249
250 250 %edit runs an external text editor. You will need to set the command for
251 251 this editor via the ``TerminalInteractiveShell.editor`` option in your
252 252 configuration file before it will work.
253 253
254 254 This command allows you to conveniently edit multi-line code right in
255 255 your IPython session.
256 256
257 257 If called without arguments, %edit opens up an empty editor with a
258 258 temporary file and will execute the contents of this file when you
259 259 close it (don't forget to save it!).
260 260
261 261
262 262 Options:
263 263
264 264 -n <number>: open the editor at a specified line number. By default,
265 265 the IPython editor hook uses the unix syntax 'editor +N filename', but
266 266 you can configure this by providing your own modified hook if your
267 267 favorite editor supports line-number specifications with a different
268 268 syntax.
269 269
270 270 -p: this will call the editor with the same data as the previous time
271 271 it was used, regardless of how long ago (in your current session) it
272 272 was.
273 273
274 274 -r: use 'raw' input. This option only applies to input taken from the
275 275 user's history. By default, the 'processed' history is used, so that
276 276 magics are loaded in their transformed version to valid Python. If
277 277 this option is given, the raw input as typed as the command line is
278 278 used instead. When you exit the editor, it will be executed by
279 279 IPython's own processor.
280 280
281 281 -x: do not execute the edited code immediately upon exit. This is
282 282 mainly useful if you are editing programs which need to be called with
283 283 command line arguments, which you can then do using %run.
284 284
285 285
286 286 Arguments:
287 287
288 288 If arguments are given, the following possibilites exist:
289 289
290 290 - The arguments are numbers or pairs of colon-separated numbers (like
291 291 1 4:8 9). These are interpreted as lines of previous input to be
292 292 loaded into the editor. The syntax is the same of the %macro command.
293 293
294 294 - If the argument doesn't start with a number, it is evaluated as a
295 295 variable and its contents loaded into the editor. You can thus edit
296 296 any string which contains python code (including the result of
297 297 previous edits).
298 298
299 299 - If the argument is the name of an object (other than a string),
300 300 IPython will try to locate the file where it was defined and open the
301 301 editor at the point where it is defined. You can use `%edit function`
302 302 to load an editor exactly at the point where 'function' is defined,
303 303 edit it and have the file be executed automatically.
304 304
305 305 If the object is a macro (see %macro for details), this opens up your
306 306 specified editor with a temporary file containing the macro's data.
307 307 Upon exit, the macro is reloaded with the contents of the file.
308 308
309 309 Note: opening at an exact line is only supported under Unix, and some
310 310 editors (like kedit and gedit up to Gnome 2.8) do not understand the
311 311 '+NUMBER' parameter necessary for this feature. Good editors like
312 312 (X)Emacs, vi, jed, pico and joe all do.
313 313
314 314 - If the argument is not found as a variable, IPython will look for a
315 315 file with that name (adding .py if necessary) and load it into the
316 316 editor. It will execute its contents with execfile() when you exit,
317 317 loading any code in the file into your interactive namespace.
318 318
319 319 After executing your code, %edit will return as output the code you
320 320 typed in the editor (except when it was an existing file). This way
321 321 you can reload the code in further invocations of %edit as a variable,
322 322 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
323 323 the output.
324 324
325 325 Note that %edit is also available through the alias %ed.
326 326
327 327 This is an example of creating a simple function inside the editor and
328 328 then modifying it. First, start up the editor:
329 329
330 330 In [1]: ed
331 331 Editing... done. Executing edited code...
332 332 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
333 333
334 334 We can then call the function foo():
335 335
336 336 In [2]: foo()
337 337 foo() was defined in an editing session
338 338
339 339 Now we edit foo. IPython automatically loads the editor with the
340 340 (temporary) file where foo() was previously defined:
341 341
342 342 In [3]: ed foo
343 343 Editing... done. Executing edited code...
344 344
345 345 And if we call foo() again we get the modified version:
346 346
347 347 In [4]: foo()
348 348 foo() has now been changed!
349 349
350 350 Here is an example of how to edit a code snippet successive
351 351 times. First we call the editor:
352 352
353 353 In [5]: ed
354 354 Editing... done. Executing edited code...
355 355 hello
356 356 Out[5]: "print 'hello'n"
357 357
358 358 Now we call it again with the previous output (stored in _):
359 359
360 360 In [6]: ed _
361 361 Editing... done. Executing edited code...
362 362 hello world
363 363 Out[6]: "print 'hello world'n"
364 364
365 365 Now we call it with the output #8 (stored in _8, also as Out[8]):
366 366
367 367 In [7]: ed _8
368 368 Editing... done. Executing edited code...
369 369 hello again
370 370 Out[7]: "print 'hello again'n"
371 371 """
372 372
373 373 opts,args = self.parse_options(parameter_s,'prn:')
374 374
375 375 try:
376 376 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
377 377 except MacroToEdit as e:
378 378 # TODO: Implement macro editing over 2 processes.
379 379 print("Macro editing not yet implemented in 2-process model.")
380 380 return
381 381
382 382 # Make sure we send to the client an absolute path, in case the working
383 383 # directory of client and kernel don't match
384 384 filename = os.path.abspath(filename)
385 385
386 386 payload = {
387 387 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
388 388 'filename' : filename,
389 389 'line_number' : lineno
390 390 }
391 391 self.payload_manager.write_payload(payload)
392 392
393 393 def magic_gui(self, parameter_s=''):
394 394 """Enable or disable IPython GUI event loop integration.
395 395
396 396 %gui [GUINAME]
397 397
398 398 This magic replaces IPython's threaded shells that were activated
399 399 using the (pylab/wthread/etc.) command line flags. GUI toolkits
400 400 can now be enabled at runtime and keyboard
401 401 interrupts should work without any problems. The following toolkits
402 402 are supported: wxPython, PyQt4, PyGTK, Cocoa, and Tk::
403 403
404 404 %gui wx # enable wxPython event loop integration
405 405 %gui qt4|qt # enable PyQt4 event loop integration
406 406 %gui gtk # enable PyGTK event loop integration
407 407 %gui OSX # enable Cocoa event loop integration (requires matplotlib 1.1)
408 408 %gui tk # enable Tk event loop integration
409 409
410 410 WARNING: after any of these has been called you can simply create
411 411 an application object, but DO NOT start the event loop yourself, as
412 412 we have already handled that.
413 413 """
414 414 from IPython.zmq.ipkernel import enable_gui
415 415 opts, arg = self.parse_options(parameter_s, '')
416 416 if arg=='': arg = None
417 return enable_gui(arg)
417 try:
418 enable_gui(arg)
419 except Exception as e:
420 # print simple error message, rather than traceback if we can't
421 # hook up the GUI
422 error(str(e))
418 423
419 424 def enable_pylab(self, gui=None, import_all=True):
420 425 """Activate pylab support at runtime.
421 426
422 427 This turns on support for matplotlib, preloads into the interactive
423 428 namespace all of numpy and pylab, and configures IPython to correcdtly
424 429 interact with the GUI event loop. The GUI backend to be used can be
425 430 optionally selected with the optional :param:`gui` argument.
426 431
427 432 Parameters
428 433 ----------
429 434 gui : optional, string [default: inline]
430 435
431 436 If given, dictates the choice of matplotlib GUI backend to use
432 437 (should be one of IPython's supported backends, 'inline', 'qt', 'osx',
433 438 'tk', or 'gtk'), otherwise we use the default chosen by matplotlib
434 439 (as dictated by the matplotlib build-time options plus the user's
435 440 matplotlibrc configuration file).
436 441 """
437 442 from IPython.zmq.ipkernel import enable_gui
438 443 # We want to prevent the loading of pylab to pollute the user's
439 444 # namespace as shown by the %who* magics, so we execute the activation
440 445 # code in an empty namespace, and we update *both* user_ns and
441 446 # user_ns_hidden with this information.
442 447 ns = {}
443 # override default to inline, from auto-detect
444 gui = pylabtools.pylab_activate(ns, gui or 'inline', import_all, self)
448 try:
449 gui = pylabtools.pylab_activate(ns, gui, import_all, self)
450 except KeyError:
451 error("Backend %r not supported" % gui)
452 return
445 453 self.user_ns.update(ns)
446 454 self.user_ns_hidden.update(ns)
447 455 # Now we must activate the gui pylab wants to use, and fix %run to take
448 456 # plot updates into account
449 enable_gui(gui)
457 try:
458 enable_gui(gui)
459 except Exception as e:
460 # print simple error message, rather than traceback if we can't
461 # hook up the GUI
462 error(str(e))
450 463 self.magic_run = self._pylab_magic_run
451 464
452 465
453 466 # A few magics that are adapted to the specifics of using pexpect and a
454 467 # remote terminal
455 468
456 469 def magic_clear(self, arg_s):
457 470 """Clear the terminal."""
458 471 if os.name == 'posix':
459 472 self.shell.system("clear")
460 473 else:
461 474 self.shell.system("cls")
462 475
463 476 if os.name == 'nt':
464 477 # This is the usual name in windows
465 478 magic_cls = magic_clear
466 479
467 480 # Terminal pagers won't work over pexpect, but we do have our own pager
468 481
469 482 def magic_less(self, arg_s):
470 483 """Show a file through the pager.
471 484
472 485 Files ending in .py are syntax-highlighted."""
473 486 cont = open(arg_s).read()
474 487 if arg_s.endswith('.py'):
475 488 cont = self.shell.pycolorize(cont)
476 489 page.page(cont)
477 490
478 491 magic_more = magic_less
479 492
480 493 # Man calls a pager, so we also need to redefine it
481 494 if os.name == 'posix':
482 495 def magic_man(self, arg_s):
483 496 """Find the man page for the given command and display in pager."""
484 497 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
485 498 split=False))
486 499
487 500 # FIXME: this is specific to the GUI, so we should let the gui app load
488 501 # magics at startup that are only for the gui. Once the gui app has proper
489 502 # profile and configuration management, we can have it initialize a kernel
490 503 # with a special config file that provides these.
491 504 def magic_guiref(self, arg_s):
492 505 """Show a basic reference about the GUI console."""
493 506 from IPython.core.usage import gui_reference
494 507 page.page(gui_reference, auto_html=True)
495 508
496 509 def magic_connect_info(self, arg_s):
497 510 """Print information for connecting other clients to this kernel
498 511
499 512 It will print the contents of this session's connection file, as well as
500 513 shortcuts for local clients.
501 514
502 515 In the simplest case, when called from the most recently launched kernel,
503 516 secondary clients can be connected, simply with:
504 517
505 518 $> ipython <app> --existing
506 519
507 520 """
508 521 try:
509 522 connection_file = get_connection_file()
510 523 info = get_connection_info(unpack=False)
511 524 except Exception as e:
512 525 error("Could not get connection info: %r" % e)
513 526 return
514 527
515 528 print (info + '\n')
516 529 print ("Paste the above JSON into a file, and connect with:\n"
517 530 " $> ipython <app> --existing <file>\n"
518 531 "or, if you are local, you can connect with just:\n"
519 532 " $> ipython <app> --existing %s\n"
520 533 "or even just:\n"
521 534 " $> ipython <app> --existing\n"
522 535 "if this is the most recent IPython session you have started."
523 536 % os.path.basename(connection_file)
524 537 )
525 538
526 539 def magic_qtconsole(self, arg_s):
527 540 """Open a qtconsole connected to this kernel.
528 541
529 542 Useful for connecting a qtconsole to running notebooks, for better
530 543 debugging.
531 544 """
532 545 try:
533 546 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
534 547 except Exception as e:
535 548 error("Could not start qtconsole: %r" % e)
536 549 return
537 550
538 551
539 552 def set_next_input(self, text):
540 553 """Send the specified text to the frontend to be presented at the next
541 554 input cell."""
542 555 payload = dict(
543 556 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
544 557 text=text
545 558 )
546 559 self.payload_manager.write_payload(payload)
547 560
548 561 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now