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