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