##// END OF EJS Templates
Update IPython/frontend/terminal/interactiveshell.py...
teegaar -
Show More
@@ -1,728 +1,728 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 from __future__ import print_function
17 17
18 18 import bdb
19 19 import os
20 20 import re
21 21 import sys
22 22 import textwrap
23 23
24 24 # We need to use nested to support python 2.6, once we move to >=2.7, we can
25 25 # use the with keyword's new builtin support for nested managers
26 26 try:
27 27 from contextlib import nested
28 28 except:
29 29 from IPython.utils.nested_context import nested
30 30
31 31 from IPython.core.error import TryNext, UsageError
32 32 from IPython.core.usage import interactive_usage, default_banner
33 33 from IPython.core.inputsplitter import IPythonInputSplitter
34 34 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
35 35 from IPython.core.magic import Magics, magics_class, line_magic
36 36 from IPython.testing.skipdoctest import skip_doctest
37 37 from IPython.utils.encoding import get_stream_enc
38 38 from IPython.utils import py3compat
39 39 from IPython.utils.terminal import toggle_set_term_title, set_term_title
40 40 from IPython.utils.process import abbrev_cwd
41 41 from IPython.utils.warn import warn, error
42 42 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
43 43 from IPython.utils.traitlets import Integer, CBool, Unicode
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Utilities
47 47 #-----------------------------------------------------------------------------
48 48
49 49 def get_default_editor():
50 50 try:
51 51 ed = os.environ['EDITOR']
52 52 except KeyError:
53 53 if os.name == 'posix':
54 54 ed = 'vi' # the only one guaranteed to be there!
55 55 else:
56 56 ed = 'notepad' # same in Windows!
57 57 return ed
58 58
59 59
60 60 def get_pasted_lines(sentinel, l_input=py3compat.input):
61 61 """ Yield pasted lines until the user enters the given sentinel value.
62 62 """
63 63 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
64 64 % sentinel)
65 65 while True:
66 66 try:
67 67 l = l_input(':')
68 68 if l == sentinel:
69 69 return
70 70 else:
71 71 yield l
72 72 except EOFError:
73 73 print('<EOF>')
74 74 return
75 75
76 76
77 77 #------------------------------------------------------------------------
78 78 # Terminal-specific magics
79 79 #------------------------------------------------------------------------
80 80
81 81 @magics_class
82 82 class TerminalMagics(Magics):
83 83 def __init__(self, shell):
84 84 super(TerminalMagics, self).__init__(shell)
85 85 self.input_splitter = IPythonInputSplitter(input_mode='line')
86 86
87 87 def cleanup_input(self, block):
88 88 """Apply all possible IPython cleanups to an input block.
89 89
90 90 This means:
91 91
92 92 - remove any global leading whitespace (dedent)
93 93 - remove any email quotes ('>') if they are present in *all* lines
94 94 - apply all static inputsplitter transforms and break into sub-blocks
95 95 - apply prefilter() to each sub-block that is a single line.
96 96
97 97 Parameters
98 98 ----------
99 99 block : str
100 100 A possibly multiline input string of code.
101 101
102 102 Returns
103 103 -------
104 104 transformed block : str
105 105 The input, with all transformations above applied.
106 106 """
107 107 # We have to effectively implement client-side the loop that is done by
108 108 # the terminal frontend, and furthermore do it on a block that can
109 109 # possibly contain multiple statments pasted in one go.
110 110
111 111 # First, run the input through the block splitting code. We should
112 112 # eventually make this a self-contained method in the inputsplitter.
113 113 isp = self.input_splitter
114 114 isp.reset()
115 115 b = textwrap.dedent(block)
116 116
117 117 # Remove email quotes first. These must be consistently applied to
118 118 # *all* lines to be removed
119 119 b = strip_email_quotes(b)
120 120
121 121 # Split the input into independent sub-blocks so we can later do
122 122 # prefiltering (which must be done *only* to single-line inputs)
123 123 blocks = []
124 124 last_block = []
125 125 for line in b.splitlines():
126 126 isp.push(line)
127 127 last_block.append(line)
128 128 if not isp.push_accepts_more():
129 129 blocks.append(isp.source_reset())
130 130 last_block = []
131 131 if last_block:
132 132 blocks.append('\n'.join(last_block))
133 133
134 134 # Now, apply prefiltering to any one-line block to match the behavior
135 135 # of the interactive terminal
136 136 final_blocks = []
137 137 for block in blocks:
138 138 lines = block.splitlines()
139 139 if len(lines) == 1:
140 140 final_blocks.append(self.shell.prefilter(lines[0]))
141 141 else:
142 142 final_blocks.append(block)
143 143
144 144 # We now have the final version of the input code as a list of blocks,
145 145 # with all inputsplitter transformations applied and single-line blocks
146 146 # run through prefilter. For further processing, turn into a single
147 147 # string as the rest of our apis use string inputs.
148 148 return '\n'.join(final_blocks)
149 149
150 150 def store_or_execute(self, block, name):
151 151 """ Execute a block, or store it in a variable, per the user's request.
152 152 """
153 153 b = self.cleanup_input(block)
154 154 if name:
155 155 # If storing it for further editing
156 156 self.shell.user_ns[name] = SList(b.splitlines())
157 157 print("Block assigned to '%s'" % name)
158 158 else:
159 159 self.shell.user_ns['pasted_block'] = b
160 160 self.shell.run_cell(b)
161 161
162 162 def rerun_pasted(self, name='pasted_block'):
163 163 """ Rerun a previously pasted command.
164 164 """
165 165 b = self.shell.user_ns.get(name)
166 166
167 167 # Sanity checks
168 168 if b is None:
169 169 raise UsageError('No previous pasted block available')
170 170 if not isinstance(b, basestring):
171 171 raise UsageError(
172 172 "Variable 'pasted_block' is not a string, can't execute")
173 173
174 174 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
175 175 self.shell.run_cell(b)
176 176
177 177 @line_magic
178 178 def autoindent(self, parameter_s = ''):
179 179 """Toggle autoindent on/off (if available)."""
180 180
181 181 self.shell.set_autoindent()
182 182 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
183 183
184 184 @skip_doctest
185 185 @line_magic
186 186 def cpaste(self, parameter_s=''):
187 187 """Paste & execute a pre-formatted code block from clipboard.
188 188
189 189 You must terminate the block with '--' (two minus-signs) or Ctrl-D
190 190 alone on the line. You can also provide your own sentinel with '%paste
191 191 -s %%' ('%%' is the new sentinel for this operation)
192 192
193 193 The block is dedented prior to execution to enable execution of method
194 194 definitions. '>' and '+' characters at the beginning of a line are
195 195 ignored, to allow pasting directly from e-mails, diff files and
196 196 doctests (the '...' continuation prompt is also stripped). The
197 197 executed block is also assigned to variable named 'pasted_block' for
198 198 later editing with '%edit pasted_block'.
199 199
200 200 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
201 201 This assigns the pasted block to variable 'foo' as string, without
202 202 dedenting or executing it (preceding >>> and + is still stripped)
203 203
204 204 '%cpaste -r' re-executes the block previously entered by cpaste.
205 205
206 206 Do not be alarmed by garbled output on Windows (it's a readline bug).
207 207 Just press enter and type -- (and press enter again) and the block
208 208 will be what was just pasted.
209 209
210 210 IPython statements (magics, shell escapes) are not supported (yet).
211 211
212 212 See also
213 213 --------
214 214 paste: automatically pull code from clipboard.
215 215
216 216 Examples
217 217 --------
218 218 ::
219 219
220 220 In [8]: %cpaste
221 221 Pasting code; enter '--' alone on the line to stop.
222 222 :>>> a = ["world!", "Hello"]
223 223 :>>> print " ".join(sorted(a))
224 224 :--
225 225 Hello world!
226 226 """
227 227 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
228 228 if 'r' in opts:
229 229 self.rerun_pasted()
230 230 return
231 231
232 232 sentinel = opts.get('s', '--')
233 233 block = '\n'.join(get_pasted_lines(sentinel))
234 234 self.store_or_execute(block, name)
235 235
236 236 @line_magic
237 237 def paste(self, parameter_s=''):
238 238 """Paste & execute a pre-formatted code block from clipboard.
239 239
240 240 The text is pulled directly from the clipboard without user
241 241 intervention and printed back on the screen before execution (unless
242 242 the -q flag is given to force quiet mode).
243 243
244 244 The block is dedented prior to execution to enable execution of method
245 245 definitions. '>' and '+' characters at the beginning of a line are
246 246 ignored, to allow pasting directly from e-mails, diff files and
247 247 doctests (the '...' continuation prompt is also stripped). The
248 248 executed block is also assigned to variable named 'pasted_block' for
249 249 later editing with '%edit pasted_block'.
250 250
251 251 You can also pass a variable name as an argument, e.g. '%paste foo'.
252 252 This assigns the pasted block to variable 'foo' as string, without
253 253 executing it (preceding >>> and + is still stripped).
254 254
255 255 Options
256 256 -------
257 257
258 258 -r: re-executes the block previously entered by cpaste.
259 259
260 260 -q: quiet mode: do not echo the pasted text back to the terminal.
261 261
262 262 IPython statements (magics, shell escapes) are not supported (yet).
263 263
264 264 See also
265 265 --------
266 266 cpaste: manually paste code into terminal until you mark its end.
267 267 """
268 268 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
269 269 if 'r' in opts:
270 270 self.rerun_pasted()
271 271 return
272 272 try:
273 273 block = self.shell.hooks.clipboard_get()
274 274 except TryNext as clipboard_exc:
275 275 message = getattr(clipboard_exc, 'args')
276 276 if message:
277 277 error(message[0])
278 278 else:
279 279 error('Could not get text from the clipboard.')
280 280 return
281 281
282 282 # By default, echo back to terminal unless quiet mode is requested
283 283 if 'q' not in opts:
284 284 write = self.shell.write
285 285 write(self.shell.pycolorize(block))
286 286 if not block.endswith('\n'):
287 287 write('\n')
288 288 write("## -- End pasted text --\n")
289 289
290 290 self.store_or_execute(block, name)
291 291
292 292 # Class-level: add a '%cls' magic only on Windows
293 293 if sys.platform == 'win32':
294 294 @line_magic
295 295 def cls(self, s):
296 296 """Clear screen.
297 297 """
298 298 os.system("cls")
299 299
300 300 #-----------------------------------------------------------------------------
301 301 # Main class
302 302 #-----------------------------------------------------------------------------
303 303
304 304 class TerminalInteractiveShell(InteractiveShell):
305 305
306 306 autoedit_syntax = CBool(False, config=True,
307 307 help="auto editing of files with syntax errors.")
308 308 banner = Unicode('')
309 309 banner1 = Unicode(default_banner, config=True,
310 310 help="""The part of the banner to be printed before the profile"""
311 311 )
312 312 banner2 = Unicode('', config=True,
313 313 help="""The part of the banner to be printed after the profile"""
314 314 )
315 315 confirm_exit = CBool(True, config=True,
316 316 help="""
317 317 Set to confirm when you try to exit IPython with an EOF (Control-D
318 318 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
319 319 you can force a direct exit without any confirmation.""",
320 320 )
321 321 # This display_banner only controls whether or not self.show_banner()
322 322 # is called when mainloop/interact are called. The default is False
323 323 # because for the terminal based application, the banner behavior
324 324 # is controlled by Global.display_banner, which IPythonApp looks at
325 325 # to determine if *it* should call show_banner() by hand or not.
326 326 display_banner = CBool(False) # This isn't configurable!
327 327 embedded = CBool(False)
328 328 embedded_active = CBool(False)
329 329 editor = Unicode(get_default_editor(), config=True,
330 330 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
331 331 )
332 332 pager = Unicode('less', config=True,
333 333 help="The shell program to be used for paging.")
334 334
335 335 screen_length = Integer(0, config=True,
336 336 help=
337 337 """Number of lines of your screen, used to control printing of very
338 338 long strings. Strings longer than this number of lines will be sent
339 339 through a pager instead of directly printed. The default value for
340 340 this is 0, which means IPython will auto-detect your screen size every
341 341 time it needs to print certain potentially long strings (this doesn't
342 342 change the behavior of the 'print' keyword, it's only triggered
343 343 internally). If for some reason this isn't working well (it needs
344 344 curses support), specify it yourself. Otherwise don't change the
345 345 default.""",
346 346 )
347 347 term_title = CBool(False, config=True,
348 348 help="Enable auto setting the terminal title."
349 349 )
350 350
351 351 # In the terminal, GUI control is done via PyOS_InputHook
352 352 from IPython.lib.inputhook import enable_gui
353 353 enable_gui = staticmethod(enable_gui)
354 354
355 355 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
356 356 user_ns=None, user_module=None, custom_exceptions=((),None),
357 357 usage=None, banner1=None, banner2=None, display_banner=None):
358 358
359 359 super(TerminalInteractiveShell, self).__init__(
360 config=config, profile_dir=profile_dir, user_ns=user_ns,
360 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
361 361 user_module=user_module, custom_exceptions=custom_exceptions
362 362 )
363 363 # use os.system instead of utils.process.system by default,
364 364 # because piped system doesn't make sense in the Terminal:
365 365 self.system = self.system_raw
366 366
367 367 self.init_term_title()
368 368 self.init_usage(usage)
369 369 self.init_banner(banner1, banner2, display_banner)
370 370
371 371 #-------------------------------------------------------------------------
372 372 # Things related to the terminal
373 373 #-------------------------------------------------------------------------
374 374
375 375 @property
376 376 def usable_screen_length(self):
377 377 if self.screen_length == 0:
378 378 return 0
379 379 else:
380 380 num_lines_bot = self.separate_in.count('\n')+1
381 381 return self.screen_length - num_lines_bot
382 382
383 383 def init_term_title(self):
384 384 # Enable or disable the terminal title.
385 385 if self.term_title:
386 386 toggle_set_term_title(True)
387 387 set_term_title('IPython: ' + abbrev_cwd())
388 388 else:
389 389 toggle_set_term_title(False)
390 390
391 391 #-------------------------------------------------------------------------
392 392 # Things related to aliases
393 393 #-------------------------------------------------------------------------
394 394
395 395 def init_alias(self):
396 396 # The parent class defines aliases that can be safely used with any
397 397 # frontend.
398 398 super(TerminalInteractiveShell, self).init_alias()
399 399
400 400 # Now define aliases that only make sense on the terminal, because they
401 401 # need direct access to the console in a way that we can't emulate in
402 402 # GUI or web frontend
403 403 if os.name == 'posix':
404 404 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
405 405 ('man', 'man')]
406 406 elif os.name == 'nt':
407 407 aliases = [('cls', 'cls')]
408 408
409 409
410 410 for name, cmd in aliases:
411 411 self.alias_manager.define_alias(name, cmd)
412 412
413 413 #-------------------------------------------------------------------------
414 414 # Things related to the banner and usage
415 415 #-------------------------------------------------------------------------
416 416
417 417 def _banner1_changed(self):
418 418 self.compute_banner()
419 419
420 420 def _banner2_changed(self):
421 421 self.compute_banner()
422 422
423 423 def _term_title_changed(self, name, new_value):
424 424 self.init_term_title()
425 425
426 426 def init_banner(self, banner1, banner2, display_banner):
427 427 if banner1 is not None:
428 428 self.banner1 = banner1
429 429 if banner2 is not None:
430 430 self.banner2 = banner2
431 431 if display_banner is not None:
432 432 self.display_banner = display_banner
433 433 self.compute_banner()
434 434
435 435 def show_banner(self, banner=None):
436 436 if banner is None:
437 437 banner = self.banner
438 438 self.write(banner)
439 439
440 440 def compute_banner(self):
441 441 self.banner = self.banner1
442 442 if self.profile and self.profile != 'default':
443 443 self.banner += '\nIPython profile: %s\n' % self.profile
444 444 if self.banner2:
445 445 self.banner += '\n' + self.banner2
446 446
447 447 def init_usage(self, usage=None):
448 448 if usage is None:
449 449 self.usage = interactive_usage
450 450 else:
451 451 self.usage = usage
452 452
453 453 #-------------------------------------------------------------------------
454 454 # Mainloop and code execution logic
455 455 #-------------------------------------------------------------------------
456 456
457 457 def mainloop(self, display_banner=None):
458 458 """Start the mainloop.
459 459
460 460 If an optional banner argument is given, it will override the
461 461 internally created default banner.
462 462 """
463 463
464 464 with nested(self.builtin_trap, self.display_trap):
465 465
466 466 while 1:
467 467 try:
468 468 self.interact(display_banner=display_banner)
469 469 #self.interact_with_readline()
470 470 # XXX for testing of a readline-decoupled repl loop, call
471 471 # interact_with_readline above
472 472 break
473 473 except KeyboardInterrupt:
474 474 # this should not be necessary, but KeyboardInterrupt
475 475 # handling seems rather unpredictable...
476 476 self.write("\nKeyboardInterrupt in interact()\n")
477 477
478 478 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
479 479 """Store multiple lines as a single entry in history"""
480 480
481 481 # do nothing without readline or disabled multiline
482 482 if not self.has_readline or not self.multiline_history:
483 483 return hlen_before_cell
484 484
485 485 # windows rl has no remove_history_item
486 486 if not hasattr(self.readline, "remove_history_item"):
487 487 return hlen_before_cell
488 488
489 489 # skip empty cells
490 490 if not source_raw.rstrip():
491 491 return hlen_before_cell
492 492
493 493 # nothing changed do nothing, e.g. when rl removes consecutive dups
494 494 hlen = self.readline.get_current_history_length()
495 495 if hlen == hlen_before_cell:
496 496 return hlen_before_cell
497 497
498 498 for i in range(hlen - hlen_before_cell):
499 499 self.readline.remove_history_item(hlen - i - 1)
500 500 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
501 501 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
502 502 stdin_encoding))
503 503 return self.readline.get_current_history_length()
504 504
505 505 def interact(self, display_banner=None):
506 506 """Closely emulate the interactive Python console."""
507 507
508 508 # batch run -> do not interact
509 509 if self.exit_now:
510 510 return
511 511
512 512 if display_banner is None:
513 513 display_banner = self.display_banner
514 514
515 515 if isinstance(display_banner, basestring):
516 516 self.show_banner(display_banner)
517 517 elif display_banner:
518 518 self.show_banner()
519 519
520 520 more = False
521 521
522 522 if self.has_readline:
523 523 self.readline_startup_hook(self.pre_readline)
524 524 hlen_b4_cell = self.readline.get_current_history_length()
525 525 else:
526 526 hlen_b4_cell = 0
527 527 # exit_now is set by a call to %Exit or %Quit, through the
528 528 # ask_exit callback.
529 529
530 530 while not self.exit_now:
531 531 self.hooks.pre_prompt_hook()
532 532 if more:
533 533 try:
534 534 prompt = self.prompt_manager.render('in2')
535 535 except:
536 536 self.showtraceback()
537 537 if self.autoindent:
538 538 self.rl_do_indent = True
539 539
540 540 else:
541 541 try:
542 542 prompt = self.separate_in + self.prompt_manager.render('in')
543 543 except:
544 544 self.showtraceback()
545 545 try:
546 546 line = self.raw_input(prompt)
547 547 if self.exit_now:
548 548 # quick exit on sys.std[in|out] close
549 549 break
550 550 if self.autoindent:
551 551 self.rl_do_indent = False
552 552
553 553 except KeyboardInterrupt:
554 554 #double-guard against keyboardinterrupts during kbdint handling
555 555 try:
556 556 self.write('\nKeyboardInterrupt\n')
557 557 source_raw = self.input_splitter.source_raw_reset()[1]
558 558 hlen_b4_cell = \
559 559 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
560 560 more = False
561 561 except KeyboardInterrupt:
562 562 pass
563 563 except EOFError:
564 564 if self.autoindent:
565 565 self.rl_do_indent = False
566 566 if self.has_readline:
567 567 self.readline_startup_hook(None)
568 568 self.write('\n')
569 569 self.exit()
570 570 except bdb.BdbQuit:
571 571 warn('The Python debugger has exited with a BdbQuit exception.\n'
572 572 'Because of how pdb handles the stack, it is impossible\n'
573 573 'for IPython to properly format this particular exception.\n'
574 574 'IPython will resume normal operation.')
575 575 except:
576 576 # exceptions here are VERY RARE, but they can be triggered
577 577 # asynchronously by signal handlers, for example.
578 578 self.showtraceback()
579 579 else:
580 580 self.input_splitter.push(line)
581 581 more = self.input_splitter.push_accepts_more()
582 582 if (self.SyntaxTB.last_syntax_error and
583 583 self.autoedit_syntax):
584 584 self.edit_syntax_error()
585 585 if not more:
586 586 source_raw = self.input_splitter.source_raw_reset()[1]
587 587 self.run_cell(source_raw, store_history=True)
588 588 hlen_b4_cell = \
589 589 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
590 590
591 591 # Turn off the exit flag, so the mainloop can be restarted if desired
592 592 self.exit_now = False
593 593
594 594 def raw_input(self, prompt=''):
595 595 """Write a prompt and read a line.
596 596
597 597 The returned line does not include the trailing newline.
598 598 When the user enters the EOF key sequence, EOFError is raised.
599 599
600 600 Optional inputs:
601 601
602 602 - prompt(''): a string to be printed to prompt the user.
603 603
604 604 - continue_prompt(False): whether this line is the first one or a
605 605 continuation in a sequence of inputs.
606 606 """
607 607 # Code run by the user may have modified the readline completer state.
608 608 # We must ensure that our completer is back in place.
609 609
610 610 if self.has_readline:
611 611 self.set_readline_completer()
612 612
613 613 # raw_input expects str, but we pass it unicode sometimes
614 614 prompt = py3compat.cast_bytes_py2(prompt)
615 615
616 616 try:
617 617 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
618 618 except ValueError:
619 619 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
620 620 " or sys.stdout.close()!\nExiting IPython!\n")
621 621 self.ask_exit()
622 622 return ""
623 623
624 624 # Try to be reasonably smart about not re-indenting pasted input more
625 625 # than necessary. We do this by trimming out the auto-indent initial
626 626 # spaces, if the user's actual input started itself with whitespace.
627 627 if self.autoindent:
628 628 if num_ini_spaces(line) > self.indent_current_nsp:
629 629 line = line[self.indent_current_nsp:]
630 630 self.indent_current_nsp = 0
631 631
632 632 return line
633 633
634 634 #-------------------------------------------------------------------------
635 635 # Methods to support auto-editing of SyntaxErrors.
636 636 #-------------------------------------------------------------------------
637 637
638 638 def edit_syntax_error(self):
639 639 """The bottom half of the syntax error handler called in the main loop.
640 640
641 641 Loop until syntax error is fixed or user cancels.
642 642 """
643 643
644 644 while self.SyntaxTB.last_syntax_error:
645 645 # copy and clear last_syntax_error
646 646 err = self.SyntaxTB.clear_err_state()
647 647 if not self._should_recompile(err):
648 648 return
649 649 try:
650 650 # may set last_syntax_error again if a SyntaxError is raised
651 651 self.safe_execfile(err.filename,self.user_ns)
652 652 except:
653 653 self.showtraceback()
654 654 else:
655 655 try:
656 656 f = open(err.filename)
657 657 try:
658 658 # This should be inside a display_trap block and I
659 659 # think it is.
660 660 sys.displayhook(f.read())
661 661 finally:
662 662 f.close()
663 663 except:
664 664 self.showtraceback()
665 665
666 666 def _should_recompile(self,e):
667 667 """Utility routine for edit_syntax_error"""
668 668
669 669 if e.filename in ('<ipython console>','<input>','<string>',
670 670 '<console>','<BackgroundJob compilation>',
671 671 None):
672 672
673 673 return False
674 674 try:
675 675 if (self.autoedit_syntax and
676 676 not self.ask_yes_no('Return to editor to correct syntax error? '
677 677 '[Y/n] ','y')):
678 678 return False
679 679 except EOFError:
680 680 return False
681 681
682 682 def int0(x):
683 683 try:
684 684 return int(x)
685 685 except TypeError:
686 686 return 0
687 687 # always pass integer line and offset values to editor hook
688 688 try:
689 689 self.hooks.fix_error_editor(e.filename,
690 690 int0(e.lineno),int0(e.offset),e.msg)
691 691 except TryNext:
692 692 warn('Could not open editor')
693 693 return False
694 694 return True
695 695
696 696 #-------------------------------------------------------------------------
697 697 # Things related to exiting
698 698 #-------------------------------------------------------------------------
699 699
700 700 def ask_exit(self):
701 701 """ Ask the shell to exit. Can be overiden and used as a callback. """
702 702 self.exit_now = True
703 703
704 704 def exit(self):
705 705 """Handle interactive exit.
706 706
707 707 This method calls the ask_exit callback."""
708 708 if self.confirm_exit:
709 709 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
710 710 self.ask_exit()
711 711 else:
712 712 self.ask_exit()
713 713
714 714 #-------------------------------------------------------------------------
715 715 # Things related to magics
716 716 #-------------------------------------------------------------------------
717 717
718 718 def init_magics(self):
719 719 super(TerminalInteractiveShell, self).init_magics()
720 720 self.register_magics(TerminalMagics)
721 721
722 722 def showindentationerror(self):
723 723 super(TerminalInteractiveShell, self).showindentationerror()
724 724 print("If you want to paste code into IPython, try the "
725 725 "%paste and %cpaste magic functions.")
726 726
727 727
728 728 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now