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