/IPython/frontend/terminal/interactiveshell.py

http://github.com/ipython/ipython · Python · 668 lines · 563 code · 23 blank · 82 comment · 30 complexity · a3f66a5d4f49f61e90a2a2716c0b90d5 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. """Subclass of InteractiveShell for terminal based frontends."""
  3. #-----------------------------------------------------------------------------
  4. # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
  5. # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
  6. # Copyright (C) 2008-2011 The IPython Development Team
  7. #
  8. # Distributed under the terms of the BSD License. The full license is in
  9. # the file COPYING, distributed as part of this software.
  10. #-----------------------------------------------------------------------------
  11. #-----------------------------------------------------------------------------
  12. # Imports
  13. #-----------------------------------------------------------------------------
  14. import __builtin__
  15. import bdb
  16. import os
  17. import re
  18. import sys
  19. import textwrap
  20. try:
  21. from contextlib import nested
  22. except:
  23. from IPython.utils.nested_context import nested
  24. from IPython.core.error import TryNext
  25. from IPython.core.usage import interactive_usage, default_banner
  26. from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
  27. from IPython.core.pylabtools import pylab_activate
  28. from IPython.testing.skipdoctest import skip_doctest
  29. from IPython.utils import py3compat
  30. from IPython.utils.terminal import toggle_set_term_title, set_term_title
  31. from IPython.utils.process import abbrev_cwd
  32. from IPython.utils.warn import warn, error
  33. from IPython.utils.text import num_ini_spaces, SList
  34. from IPython.utils.traitlets import Integer, CBool, Unicode
  35. #-----------------------------------------------------------------------------
  36. # Utilities
  37. #-----------------------------------------------------------------------------
  38. def get_default_editor():
  39. try:
  40. ed = os.environ['EDITOR']
  41. except KeyError:
  42. if os.name == 'posix':
  43. ed = 'vi' # the only one guaranteed to be there!
  44. else:
  45. ed = 'notepad' # same in Windows!
  46. return ed
  47. def get_pasted_lines(sentinel, l_input=py3compat.input):
  48. """ Yield pasted lines until the user enters the given sentinel value.
  49. """
  50. print "Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
  51. % sentinel
  52. while True:
  53. try:
  54. l = l_input(':')
  55. if l == sentinel:
  56. return
  57. else:
  58. yield l
  59. except EOFError:
  60. print '<EOF>'
  61. return
  62. def strip_email_quotes(raw_lines):
  63. """ Strip email quotation marks at the beginning of each line.
  64. We don't do any more input transofrmations here because the main shell's
  65. prefiltering handles other cases.
  66. """
  67. lines = [re.sub(r'^\s*(\s?>)+', '', l) for l in raw_lines]
  68. return '\n'.join(lines) + '\n'
  69. # These two functions are needed by the %paste/%cpaste magics. In practice
  70. # they are basically methods (they take the shell as their first argument), but
  71. # we leave them as standalone functions because eventually the magics
  72. # themselves will become separate objects altogether. At that point, the
  73. # magics will have access to the shell object, and these functions can be made
  74. # methods of the magic object, but not of the shell.
  75. def store_or_execute(shell, block, name):
  76. """ Execute a block, or store it in a variable, per the user's request.
  77. """
  78. # Dedent and prefilter so what we store matches what is executed by
  79. # run_cell.
  80. b = shell.prefilter(textwrap.dedent(block))
  81. if name:
  82. # If storing it for further editing, run the prefilter on it
  83. shell.user_ns[name] = SList(b.splitlines())
  84. print "Block assigned to '%s'" % name
  85. else:
  86. shell.user_ns['pasted_block'] = b
  87. shell.run_cell(b)
  88. def rerun_pasted(shell, name='pasted_block'):
  89. """ Rerun a previously pasted command.
  90. """
  91. b = shell.user_ns.get(name)
  92. # Sanity checks
  93. if b is None:
  94. raise UsageError('No previous pasted block available')
  95. if not isinstance(b, basestring):
  96. raise UsageError(
  97. "Variable 'pasted_block' is not a string, can't execute")
  98. print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
  99. shell.run_cell(b)
  100. #-----------------------------------------------------------------------------
  101. # Main class
  102. #-----------------------------------------------------------------------------
  103. class TerminalInteractiveShell(InteractiveShell):
  104. autoedit_syntax = CBool(False, config=True,
  105. help="auto editing of files with syntax errors.")
  106. banner = Unicode('')
  107. banner1 = Unicode(default_banner, config=True,
  108. help="""The part of the banner to be printed before the profile"""
  109. )
  110. banner2 = Unicode('', config=True,
  111. help="""The part of the banner to be printed after the profile"""
  112. )
  113. confirm_exit = CBool(True, config=True,
  114. help="""
  115. Set to confirm when you try to exit IPython with an EOF (Control-D
  116. in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
  117. you can force a direct exit without any confirmation.""",
  118. )
  119. # This display_banner only controls whether or not self.show_banner()
  120. # is called when mainloop/interact are called. The default is False
  121. # because for the terminal based application, the banner behavior
  122. # is controlled by Global.display_banner, which IPythonApp looks at
  123. # to determine if *it* should call show_banner() by hand or not.
  124. display_banner = CBool(False) # This isn't configurable!
  125. embedded = CBool(False)
  126. embedded_active = CBool(False)
  127. editor = Unicode(get_default_editor(), config=True,
  128. help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
  129. )
  130. pager = Unicode('less', config=True,
  131. help="The shell program to be used for paging.")
  132. screen_length = Integer(0, config=True,
  133. help=
  134. """Number of lines of your screen, used to control printing of very
  135. long strings. Strings longer than this number of lines will be sent
  136. through a pager instead of directly printed. The default value for
  137. this is 0, which means IPython will auto-detect your screen size every
  138. time it needs to print certain potentially long strings (this doesn't
  139. change the behavior of the 'print' keyword, it's only triggered
  140. internally). If for some reason this isn't working well (it needs
  141. curses support), specify it yourself. Otherwise don't change the
  142. default.""",
  143. )
  144. term_title = CBool(False, config=True,
  145. help="Enable auto setting the terminal title."
  146. )
  147. # In the terminal, GUI control is done via PyOS_InputHook
  148. from IPython.lib.inputhook import enable_gui
  149. enable_gui = staticmethod(enable_gui)
  150. def __init__(self, config=None, ipython_dir=None, profile_dir=None,
  151. user_ns=None, user_module=None, custom_exceptions=((),None),
  152. usage=None, banner1=None, banner2=None, display_banner=None):
  153. super(TerminalInteractiveShell, self).__init__(
  154. config=config, profile_dir=profile_dir, user_ns=user_ns,
  155. user_module=user_module, custom_exceptions=custom_exceptions
  156. )
  157. # use os.system instead of utils.process.system by default,
  158. # because piped system doesn't make sense in the Terminal:
  159. self.system = self.system_raw
  160. self.init_term_title()
  161. self.init_usage(usage)
  162. self.init_banner(banner1, banner2, display_banner)
  163. #-------------------------------------------------------------------------
  164. # Things related to the terminal
  165. #-------------------------------------------------------------------------
  166. @property
  167. def usable_screen_length(self):
  168. if self.screen_length == 0:
  169. return 0
  170. else:
  171. num_lines_bot = self.separate_in.count('\n')+1
  172. return self.screen_length - num_lines_bot
  173. def init_term_title(self):
  174. # Enable or disable the terminal title.
  175. if self.term_title:
  176. toggle_set_term_title(True)
  177. set_term_title('IPython: ' + abbrev_cwd())
  178. else:
  179. toggle_set_term_title(False)
  180. #-------------------------------------------------------------------------
  181. # Things related to aliases
  182. #-------------------------------------------------------------------------
  183. def init_alias(self):
  184. # The parent class defines aliases that can be safely used with any
  185. # frontend.
  186. super(TerminalInteractiveShell, self).init_alias()
  187. # Now define aliases that only make sense on the terminal, because they
  188. # need direct access to the console in a way that we can't emulate in
  189. # GUI or web frontend
  190. if os.name == 'posix':
  191. aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
  192. ('man', 'man')]
  193. elif os.name == 'nt':
  194. aliases = [('cls', 'cls')]
  195. for name, cmd in aliases:
  196. self.alias_manager.define_alias(name, cmd)
  197. #-------------------------------------------------------------------------
  198. # Things related to the banner and usage
  199. #-------------------------------------------------------------------------
  200. def _banner1_changed(self):
  201. self.compute_banner()
  202. def _banner2_changed(self):
  203. self.compute_banner()
  204. def _term_title_changed(self, name, new_value):
  205. self.init_term_title()
  206. def init_banner(self, banner1, banner2, display_banner):
  207. if banner1 is not None:
  208. self.banner1 = banner1
  209. if banner2 is not None:
  210. self.banner2 = banner2
  211. if display_banner is not None:
  212. self.display_banner = display_banner
  213. self.compute_banner()
  214. def show_banner(self, banner=None):
  215. if banner is None:
  216. banner = self.banner
  217. self.write(banner)
  218. def compute_banner(self):
  219. self.banner = self.banner1
  220. if self.profile and self.profile != 'default':
  221. self.banner += '\nIPython profile: %s\n' % self.profile
  222. if self.banner2:
  223. self.banner += '\n' + self.banner2
  224. def init_usage(self, usage=None):
  225. if usage is None:
  226. self.usage = interactive_usage
  227. else:
  228. self.usage = usage
  229. #-------------------------------------------------------------------------
  230. # Mainloop and code execution logic
  231. #-------------------------------------------------------------------------
  232. def mainloop(self, display_banner=None):
  233. """Start the mainloop.
  234. If an optional banner argument is given, it will override the
  235. internally created default banner.
  236. """
  237. with nested(self.builtin_trap, self.display_trap):
  238. while 1:
  239. try:
  240. self.interact(display_banner=display_banner)
  241. #self.interact_with_readline()
  242. # XXX for testing of a readline-decoupled repl loop, call
  243. # interact_with_readline above
  244. break
  245. except KeyboardInterrupt:
  246. # this should not be necessary, but KeyboardInterrupt
  247. # handling seems rather unpredictable...
  248. self.write("\nKeyboardInterrupt in interact()\n")
  249. def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
  250. """Store multiple lines as a single entry in history"""
  251. # do nothing without readline or disabled multiline
  252. if not self.has_readline or not self.multiline_history:
  253. return hlen_before_cell
  254. # windows rl has no remove_history_item
  255. if not hasattr(self.readline, "remove_history_item"):
  256. return hlen_before_cell
  257. # skip empty cells
  258. if not source_raw.rstrip():
  259. return hlen_before_cell
  260. # nothing changed do nothing, e.g. when rl removes consecutive dups
  261. hlen = self.readline.get_current_history_length()
  262. if hlen == hlen_before_cell:
  263. return hlen_before_cell
  264. for i in range(hlen - hlen_before_cell):
  265. self.readline.remove_history_item(hlen - i - 1)
  266. stdin_encoding = sys.stdin.encoding or "utf-8"
  267. self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
  268. stdin_encoding))
  269. return self.readline.get_current_history_length()
  270. def interact(self, display_banner=None):
  271. """Closely emulate the interactive Python console."""
  272. # batch run -> do not interact
  273. if self.exit_now:
  274. return
  275. if display_banner is None:
  276. display_banner = self.display_banner
  277. if isinstance(display_banner, basestring):
  278. self.show_banner(display_banner)
  279. elif display_banner:
  280. self.show_banner()
  281. more = False
  282. if self.has_readline:
  283. self.readline_startup_hook(self.pre_readline)
  284. hlen_b4_cell = self.readline.get_current_history_length()
  285. else:
  286. hlen_b4_cell = 0
  287. # exit_now is set by a call to %Exit or %Quit, through the
  288. # ask_exit callback.
  289. while not self.exit_now:
  290. self.hooks.pre_prompt_hook()
  291. if more:
  292. try:
  293. prompt = self.prompt_manager.render('in2')
  294. except:
  295. self.showtraceback()
  296. if self.autoindent:
  297. self.rl_do_indent = True
  298. else:
  299. try:
  300. prompt = self.separate_in + self.prompt_manager.render('in')
  301. except:
  302. self.showtraceback()
  303. try:
  304. line = self.raw_input(prompt)
  305. if self.exit_now:
  306. # quick exit on sys.std[in|out] close
  307. break
  308. if self.autoindent:
  309. self.rl_do_indent = False
  310. except KeyboardInterrupt:
  311. #double-guard against keyboardinterrupts during kbdint handling
  312. try:
  313. self.write('\nKeyboardInterrupt\n')
  314. source_raw = self.input_splitter.source_raw_reset()[1]
  315. hlen_b4_cell = \
  316. self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
  317. more = False
  318. except KeyboardInterrupt:
  319. pass
  320. except EOFError:
  321. if self.autoindent:
  322. self.rl_do_indent = False
  323. if self.has_readline:
  324. self.readline_startup_hook(None)
  325. self.write('\n')
  326. self.exit()
  327. except bdb.BdbQuit:
  328. warn('The Python debugger has exited with a BdbQuit exception.\n'
  329. 'Because of how pdb handles the stack, it is impossible\n'
  330. 'for IPython to properly format this particular exception.\n'
  331. 'IPython will resume normal operation.')
  332. except:
  333. # exceptions here are VERY RARE, but they can be triggered
  334. # asynchronously by signal handlers, for example.
  335. self.showtraceback()
  336. else:
  337. self.input_splitter.push(line)
  338. more = self.input_splitter.push_accepts_more()
  339. if (self.SyntaxTB.last_syntax_error and
  340. self.autoedit_syntax):
  341. self.edit_syntax_error()
  342. if not more:
  343. source_raw = self.input_splitter.source_raw_reset()[1]
  344. self.run_cell(source_raw, store_history=True)
  345. hlen_b4_cell = \
  346. self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
  347. # Turn off the exit flag, so the mainloop can be restarted if desired
  348. self.exit_now = False
  349. def raw_input(self, prompt=''):
  350. """Write a prompt and read a line.
  351. The returned line does not include the trailing newline.
  352. When the user enters the EOF key sequence, EOFError is raised.
  353. Optional inputs:
  354. - prompt(''): a string to be printed to prompt the user.
  355. - continue_prompt(False): whether this line is the first one or a
  356. continuation in a sequence of inputs.
  357. """
  358. # Code run by the user may have modified the readline completer state.
  359. # We must ensure that our completer is back in place.
  360. if self.has_readline:
  361. self.set_readline_completer()
  362. try:
  363. line = py3compat.str_to_unicode(self.raw_input_original(prompt))
  364. except ValueError:
  365. warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
  366. " or sys.stdout.close()!\nExiting IPython!")
  367. self.ask_exit()
  368. return ""
  369. # Try to be reasonably smart about not re-indenting pasted input more
  370. # than necessary. We do this by trimming out the auto-indent initial
  371. # spaces, if the user's actual input started itself with whitespace.
  372. if self.autoindent:
  373. if num_ini_spaces(line) > self.indent_current_nsp:
  374. line = line[self.indent_current_nsp:]
  375. self.indent_current_nsp = 0
  376. return line
  377. #-------------------------------------------------------------------------
  378. # Methods to support auto-editing of SyntaxErrors.
  379. #-------------------------------------------------------------------------
  380. def edit_syntax_error(self):
  381. """The bottom half of the syntax error handler called in the main loop.
  382. Loop until syntax error is fixed or user cancels.
  383. """
  384. while self.SyntaxTB.last_syntax_error:
  385. # copy and clear last_syntax_error
  386. err = self.SyntaxTB.clear_err_state()
  387. if not self._should_recompile(err):
  388. return
  389. try:
  390. # may set last_syntax_error again if a SyntaxError is raised
  391. self.safe_execfile(err.filename,self.user_ns)
  392. except:
  393. self.showtraceback()
  394. else:
  395. try:
  396. f = file(err.filename)
  397. try:
  398. # This should be inside a display_trap block and I
  399. # think it is.
  400. sys.displayhook(f.read())
  401. finally:
  402. f.close()
  403. except:
  404. self.showtraceback()
  405. def _should_recompile(self,e):
  406. """Utility routine for edit_syntax_error"""
  407. if e.filename in ('<ipython console>','<input>','<string>',
  408. '<console>','<BackgroundJob compilation>',
  409. None):
  410. return False
  411. try:
  412. if (self.autoedit_syntax and
  413. not self.ask_yes_no('Return to editor to correct syntax error? '
  414. '[Y/n] ','y')):
  415. return False
  416. except EOFError:
  417. return False
  418. def int0(x):
  419. try:
  420. return int(x)
  421. except TypeError:
  422. return 0
  423. # always pass integer line and offset values to editor hook
  424. try:
  425. self.hooks.fix_error_editor(e.filename,
  426. int0(e.lineno),int0(e.offset),e.msg)
  427. except TryNext:
  428. warn('Could not open editor')
  429. return False
  430. return True
  431. #-------------------------------------------------------------------------
  432. # Things related to exiting
  433. #-------------------------------------------------------------------------
  434. def ask_exit(self):
  435. """ Ask the shell to exit. Can be overiden and used as a callback. """
  436. self.exit_now = True
  437. def exit(self):
  438. """Handle interactive exit.
  439. This method calls the ask_exit callback."""
  440. if self.confirm_exit:
  441. if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
  442. self.ask_exit()
  443. else:
  444. self.ask_exit()
  445. #------------------------------------------------------------------------
  446. # Magic overrides
  447. #------------------------------------------------------------------------
  448. # Once the base class stops inheriting from magic, this code needs to be
  449. # moved into a separate machinery as well. For now, at least isolate here
  450. # the magics which this class needs to implement differently from the base
  451. # class, or that are unique to it.
  452. def magic_autoindent(self, parameter_s = ''):
  453. """Toggle autoindent on/off (if available)."""
  454. self.shell.set_autoindent()
  455. print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
  456. @skip_doctest
  457. def magic_cpaste(self, parameter_s=''):
  458. """Paste & execute a pre-formatted code block from clipboard.
  459. You must terminate the block with '--' (two minus-signs) or Ctrl-D
  460. alone on the line. You can also provide your own sentinel with '%paste
  461. -s %%' ('%%' is the new sentinel for this operation)
  462. The block is dedented prior to execution to enable execution of method
  463. definitions. '>' and '+' characters at the beginning of a line are
  464. ignored, to allow pasting directly from e-mails, diff files and
  465. doctests (the '...' continuation prompt is also stripped). The
  466. executed block is also assigned to variable named 'pasted_block' for
  467. later editing with '%edit pasted_block'.
  468. You can also pass a variable name as an argument, e.g. '%cpaste foo'.
  469. This assigns the pasted block to variable 'foo' as string, without
  470. dedenting or executing it (preceding >>> and + is still stripped)
  471. '%cpaste -r' re-executes the block previously entered by cpaste.
  472. Do not be alarmed by garbled output on Windows (it's a readline bug).
  473. Just press enter and type -- (and press enter again) and the block
  474. will be what was just pasted.
  475. IPython statements (magics, shell escapes) are not supported (yet).
  476. See also
  477. --------
  478. paste: automatically pull code from clipboard.
  479. Examples
  480. --------
  481. ::
  482. In [8]: %cpaste
  483. Pasting code; enter '--' alone on the line to stop.
  484. :>>> a = ["world!", "Hello"]
  485. :>>> print " ".join(sorted(a))
  486. :--
  487. Hello world!
  488. """
  489. opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
  490. if 'r' in opts:
  491. rerun_pasted(self.shell)
  492. return
  493. sentinel = opts.get('s', '--')
  494. block = strip_email_quotes(get_pasted_lines(sentinel))
  495. store_or_execute(self.shell, block, name)
  496. def magic_paste(self, parameter_s=''):
  497. """Paste & execute a pre-formatted code block from clipboard.
  498. The text is pulled directly from the clipboard without user
  499. intervention and printed back on the screen before execution (unless
  500. the -q flag is given to force quiet mode).
  501. The block is dedented prior to execution to enable execution of method
  502. definitions. '>' and '+' characters at the beginning of a line are
  503. ignored, to allow pasting directly from e-mails, diff files and
  504. doctests (the '...' continuation prompt is also stripped). The
  505. executed block is also assigned to variable named 'pasted_block' for
  506. later editing with '%edit pasted_block'.
  507. You can also pass a variable name as an argument, e.g. '%paste foo'.
  508. This assigns the pasted block to variable 'foo' as string, without
  509. dedenting or executing it (preceding >>> and + is still stripped)
  510. Options
  511. -------
  512. -r: re-executes the block previously entered by cpaste.
  513. -q: quiet mode: do not echo the pasted text back to the terminal.
  514. IPython statements (magics, shell escapes) are not supported (yet).
  515. See also
  516. --------
  517. cpaste: manually paste code into terminal until you mark its end.
  518. """
  519. opts, name = self.parse_options(parameter_s, 'rq', mode='string')
  520. if 'r' in opts:
  521. rerun_pasted(self.shell)
  522. return
  523. try:
  524. text = self.shell.hooks.clipboard_get()
  525. block = strip_email_quotes(text.splitlines())
  526. except TryNext as clipboard_exc:
  527. message = getattr(clipboard_exc, 'args')
  528. if message:
  529. error(message[0])
  530. else:
  531. error('Could not get text from the clipboard.')
  532. return
  533. # By default, echo back to terminal unless quiet mode is requested
  534. if 'q' not in opts:
  535. write = self.shell.write
  536. write(self.shell.pycolorize(block))
  537. if not block.endswith('\n'):
  538. write('\n')
  539. write("## -- End pasted text --\n")
  540. store_or_execute(self.shell, block, name)
  541. # Class-level: add a '%cls' magic only on Windows
  542. if sys.platform == 'win32':
  543. def magic_cls(self, s):
  544. """Clear screen.
  545. """
  546. os.system("cls")
  547. def showindentationerror(self):
  548. super(TerminalInteractiveShell, self).showindentationerror()
  549. print("If you want to paste code into IPython, try the "
  550. "%paste and %cpaste magic functions.")
  551. InteractiveShellABC.register(TerminalInteractiveShell)