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