basic.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. """Implementation of basic magic functions."""
  2. from __future__ import print_function
  3. from __future__ import absolute_import
  4. import io
  5. import sys
  6. from pprint import pformat
  7. from IPython.core import magic_arguments, page
  8. from IPython.core.error import UsageError
  9. from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
  10. from IPython.utils.text import format_screen, dedent, indent
  11. from IPython.testing.skipdoctest import skip_doctest
  12. from IPython.utils.ipstruct import Struct
  13. from IPython.utils.py3compat import unicode_type
  14. from warnings import warn
  15. from logging import error
  16. class MagicsDisplay(object):
  17. def __init__(self, magics_manager):
  18. self.magics_manager = magics_manager
  19. def _lsmagic(self):
  20. """The main implementation of the %lsmagic"""
  21. mesc = magic_escapes['line']
  22. cesc = magic_escapes['cell']
  23. mman = self.magics_manager
  24. magics = mman.lsmagic()
  25. out = ['Available line magics:',
  26. mesc + (' '+mesc).join(sorted(magics['line'])),
  27. '',
  28. 'Available cell magics:',
  29. cesc + (' '+cesc).join(sorted(magics['cell'])),
  30. '',
  31. mman.auto_status()]
  32. return '\n'.join(out)
  33. def _repr_pretty_(self, p, cycle):
  34. p.text(self._lsmagic())
  35. def __str__(self):
  36. return self._lsmagic()
  37. def _jsonable(self):
  38. """turn magics dict into jsonable dict of the same structure
  39. replaces object instances with their class names as strings
  40. """
  41. magic_dict = {}
  42. mman = self.magics_manager
  43. magics = mman.lsmagic()
  44. for key, subdict in magics.items():
  45. d = {}
  46. magic_dict[key] = d
  47. for name, obj in subdict.items():
  48. try:
  49. classname = obj.__self__.__class__.__name__
  50. except AttributeError:
  51. classname = 'Other'
  52. d[name] = classname
  53. return magic_dict
  54. def _repr_json_(self):
  55. return self._jsonable()
  56. @magics_class
  57. class BasicMagics(Magics):
  58. """Magics that provide central IPython functionality.
  59. These are various magics that don't fit into specific categories but that
  60. are all part of the base 'IPython experience'."""
  61. @magic_arguments.magic_arguments()
  62. @magic_arguments.argument(
  63. '-l', '--line', action='store_true',
  64. help="""Create a line magic alias."""
  65. )
  66. @magic_arguments.argument(
  67. '-c', '--cell', action='store_true',
  68. help="""Create a cell magic alias."""
  69. )
  70. @magic_arguments.argument(
  71. 'name',
  72. help="""Name of the magic to be created."""
  73. )
  74. @magic_arguments.argument(
  75. 'target',
  76. help="""Name of the existing line or cell magic."""
  77. )
  78. @line_magic
  79. def alias_magic(self, line=''):
  80. """Create an alias for an existing line or cell magic.
  81. Examples
  82. --------
  83. ::
  84. In [1]: %alias_magic t timeit
  85. Created `%t` as an alias for `%timeit`.
  86. Created `%%t` as an alias for `%%timeit`.
  87. In [2]: %t -n1 pass
  88. 1 loops, best of 3: 954 ns per loop
  89. In [3]: %%t -n1
  90. ...: pass
  91. ...:
  92. 1 loops, best of 3: 954 ns per loop
  93. In [4]: %alias_magic --cell whereami pwd
  94. UsageError: Cell magic function `%%pwd` not found.
  95. In [5]: %alias_magic --line whereami pwd
  96. Created `%whereami` as an alias for `%pwd`.
  97. In [6]: %whereami
  98. Out[6]: u'/home/testuser'
  99. """
  100. args = magic_arguments.parse_argstring(self.alias_magic, line)
  101. shell = self.shell
  102. mman = self.shell.magics_manager
  103. escs = ''.join(magic_escapes.values())
  104. target = args.target.lstrip(escs)
  105. name = args.name.lstrip(escs)
  106. # Find the requested magics.
  107. m_line = shell.find_magic(target, 'line')
  108. m_cell = shell.find_magic(target, 'cell')
  109. if args.line and m_line is None:
  110. raise UsageError('Line magic function `%s%s` not found.' %
  111. (magic_escapes['line'], target))
  112. if args.cell and m_cell is None:
  113. raise UsageError('Cell magic function `%s%s` not found.' %
  114. (magic_escapes['cell'], target))
  115. # If --line and --cell are not specified, default to the ones
  116. # that are available.
  117. if not args.line and not args.cell:
  118. if not m_line and not m_cell:
  119. raise UsageError(
  120. 'No line or cell magic with name `%s` found.' % target
  121. )
  122. args.line = bool(m_line)
  123. args.cell = bool(m_cell)
  124. if args.line:
  125. mman.register_alias(name, target, 'line')
  126. print('Created `%s%s` as an alias for `%s%s`.' % (
  127. magic_escapes['line'], name,
  128. magic_escapes['line'], target))
  129. if args.cell:
  130. mman.register_alias(name, target, 'cell')
  131. print('Created `%s%s` as an alias for `%s%s`.' % (
  132. magic_escapes['cell'], name,
  133. magic_escapes['cell'], target))
  134. @line_magic
  135. def lsmagic(self, parameter_s=''):
  136. """List currently available magic functions."""
  137. return MagicsDisplay(self.shell.magics_manager)
  138. def _magic_docs(self, brief=False, rest=False):
  139. """Return docstrings from magic functions."""
  140. mman = self.shell.magics_manager
  141. docs = mman.lsmagic_docs(brief, missing='No documentation')
  142. if rest:
  143. format_string = '**%s%s**::\n\n%s\n\n'
  144. else:
  145. format_string = '%s%s:\n%s\n'
  146. return ''.join(
  147. [format_string % (magic_escapes['line'], fname,
  148. indent(dedent(fndoc)))
  149. for fname, fndoc in sorted(docs['line'].items())]
  150. +
  151. [format_string % (magic_escapes['cell'], fname,
  152. indent(dedent(fndoc)))
  153. for fname, fndoc in sorted(docs['cell'].items())]
  154. )
  155. @line_magic
  156. def magic(self, parameter_s=''):
  157. """Print information about the magic function system.
  158. Supported formats: -latex, -brief, -rest
  159. """
  160. mode = ''
  161. try:
  162. mode = parameter_s.split()[0][1:]
  163. except IndexError:
  164. pass
  165. brief = (mode == 'brief')
  166. rest = (mode == 'rest')
  167. magic_docs = self._magic_docs(brief, rest)
  168. if mode == 'latex':
  169. print(self.format_latex(magic_docs))
  170. return
  171. else:
  172. magic_docs = format_screen(magic_docs)
  173. out = ["""
  174. IPython's 'magic' functions
  175. ===========================
  176. The magic function system provides a series of functions which allow you to
  177. control the behavior of IPython itself, plus a lot of system-type
  178. features. There are two kinds of magics, line-oriented and cell-oriented.
  179. Line magics are prefixed with the % character and work much like OS
  180. command-line calls: they get as an argument the rest of the line, where
  181. arguments are passed without parentheses or quotes. For example, this will
  182. time the given statement::
  183. %timeit range(1000)
  184. Cell magics are prefixed with a double %%, and they are functions that get as
  185. an argument not only the rest of the line, but also the lines below it in a
  186. separate argument. These magics are called with two arguments: the rest of the
  187. call line and the body of the cell, consisting of the lines below the first.
  188. For example::
  189. %%timeit x = numpy.random.randn((100, 100))
  190. numpy.linalg.svd(x)
  191. will time the execution of the numpy svd routine, running the assignment of x
  192. as part of the setup phase, which is not timed.
  193. In a line-oriented client (the terminal or Qt console IPython), starting a new
  194. input with %% will automatically enter cell mode, and IPython will continue
  195. reading input until a blank line is given. In the notebook, simply type the
  196. whole cell as one entity, but keep in mind that the %% escape can only be at
  197. the very start of the cell.
  198. NOTE: If you have 'automagic' enabled (via the command line option or with the
  199. %automagic function), you don't need to type in the % explicitly for line
  200. magics; cell magics always require an explicit '%%' escape. By default,
  201. IPython ships with automagic on, so you should only rarely need the % escape.
  202. Example: typing '%cd mydir' (without the quotes) changes your working directory
  203. to 'mydir', if it exists.
  204. For a list of the available magic functions, use %lsmagic. For a description
  205. of any of them, type %magic_name?, e.g. '%cd?'.
  206. Currently the magic system has the following functions:""",
  207. magic_docs,
  208. "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
  209. str(self.lsmagic()),
  210. ]
  211. page.page('\n'.join(out))
  212. @line_magic
  213. def page(self, parameter_s=''):
  214. """Pretty print the object and display it through a pager.
  215. %page [options] OBJECT
  216. If no object is given, use _ (last output).
  217. Options:
  218. -r: page str(object), don't pretty-print it."""
  219. # After a function contributed by Olivier Aubert, slightly modified.
  220. # Process options/args
  221. opts, args = self.parse_options(parameter_s, 'r')
  222. raw = 'r' in opts
  223. oname = args and args or '_'
  224. info = self.shell._ofind(oname)
  225. if info['found']:
  226. txt = (raw and str or pformat)( info['obj'] )
  227. page.page(txt)
  228. else:
  229. print('Object `%s` not found' % oname)
  230. @line_magic
  231. def profile(self, parameter_s=''):
  232. """Print your currently active IPython profile.
  233. See Also
  234. --------
  235. prun : run code using the Python profiler
  236. (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
  237. """
  238. warn("%profile is now deprecated. Please use get_ipython().profile instead.")
  239. from IPython.core.application import BaseIPythonApplication
  240. if BaseIPythonApplication.initialized():
  241. print(BaseIPythonApplication.instance().profile)
  242. else:
  243. error("profile is an application-level value, but you don't appear to be in an IPython application")
  244. @line_magic
  245. def pprint(self, parameter_s=''):
  246. """Toggle pretty printing on/off."""
  247. ptformatter = self.shell.display_formatter.formatters['text/plain']
  248. ptformatter.pprint = bool(1 - ptformatter.pprint)
  249. print('Pretty printing has been turned',
  250. ['OFF','ON'][ptformatter.pprint])
  251. @line_magic
  252. def colors(self, parameter_s=''):
  253. """Switch color scheme for prompts, info system and exception handlers.
  254. Currently implemented schemes: NoColor, Linux, LightBG.
  255. Color scheme names are not case-sensitive.
  256. Examples
  257. --------
  258. To get a plain black and white terminal::
  259. %colors nocolor
  260. """
  261. def color_switch_err(name):
  262. warn('Error changing %s color schemes.\n%s' %
  263. (name, sys.exc_info()[1]), stacklevel=2)
  264. new_scheme = parameter_s.strip()
  265. if not new_scheme:
  266. raise UsageError(
  267. "%colors: you must specify a color scheme. See '%colors?'")
  268. # local shortcut
  269. shell = self.shell
  270. # Set shell colour scheme
  271. try:
  272. shell.colors = new_scheme
  273. shell.refresh_style()
  274. except:
  275. color_switch_err('shell')
  276. # Set exception colors
  277. try:
  278. shell.InteractiveTB.set_colors(scheme = new_scheme)
  279. shell.SyntaxTB.set_colors(scheme = new_scheme)
  280. except:
  281. color_switch_err('exception')
  282. # Set info (for 'object?') colors
  283. if shell.color_info:
  284. try:
  285. shell.inspector.set_active_scheme(new_scheme)
  286. except:
  287. color_switch_err('object inspector')
  288. else:
  289. shell.inspector.set_active_scheme('NoColor')
  290. @line_magic
  291. def xmode(self, parameter_s=''):
  292. """Switch modes for the exception handlers.
  293. Valid modes: Plain, Context and Verbose.
  294. If called without arguments, acts as a toggle."""
  295. def xmode_switch_err(name):
  296. warn('Error changing %s exception modes.\n%s' %
  297. (name,sys.exc_info()[1]))
  298. shell = self.shell
  299. new_mode = parameter_s.strip().capitalize()
  300. try:
  301. shell.InteractiveTB.set_mode(mode=new_mode)
  302. print('Exception reporting mode:',shell.InteractiveTB.mode)
  303. except:
  304. xmode_switch_err('user')
  305. @line_magic
  306. def quickref(self,arg):
  307. """ Show a quick reference sheet """
  308. from IPython.core.usage import quick_reference
  309. qr = quick_reference + self._magic_docs(brief=True)
  310. page.page(qr)
  311. @line_magic
  312. def doctest_mode(self, parameter_s=''):
  313. """Toggle doctest mode on and off.
  314. This mode is intended to make IPython behave as much as possible like a
  315. plain Python shell, from the perspective of how its prompts, exceptions
  316. and output look. This makes it easy to copy and paste parts of a
  317. session into doctests. It does so by:
  318. - Changing the prompts to the classic ``>>>`` ones.
  319. - Changing the exception reporting mode to 'Plain'.
  320. - Disabling pretty-printing of output.
  321. Note that IPython also supports the pasting of code snippets that have
  322. leading '>>>' and '...' prompts in them. This means that you can paste
  323. doctests from files or docstrings (even if they have leading
  324. whitespace), and the code will execute correctly. You can then use
  325. '%history -t' to see the translated history; this will give you the
  326. input after removal of all the leading prompts and whitespace, which
  327. can be pasted back into an editor.
  328. With these features, you can switch into this mode easily whenever you
  329. need to do testing and changes to doctests, without having to leave
  330. your existing IPython session.
  331. """
  332. # Shorthands
  333. shell = self.shell
  334. meta = shell.meta
  335. disp_formatter = self.shell.display_formatter
  336. ptformatter = disp_formatter.formatters['text/plain']
  337. # dstore is a data store kept in the instance metadata bag to track any
  338. # changes we make, so we can undo them later.
  339. dstore = meta.setdefault('doctest_mode',Struct())
  340. save_dstore = dstore.setdefault
  341. # save a few values we'll need to recover later
  342. mode = save_dstore('mode',False)
  343. save_dstore('rc_pprint',ptformatter.pprint)
  344. save_dstore('xmode',shell.InteractiveTB.mode)
  345. save_dstore('rc_separate_out',shell.separate_out)
  346. save_dstore('rc_separate_out2',shell.separate_out2)
  347. save_dstore('rc_separate_in',shell.separate_in)
  348. save_dstore('rc_active_types',disp_formatter.active_types)
  349. if not mode:
  350. # turn on
  351. # Prompt separators like plain python
  352. shell.separate_in = ''
  353. shell.separate_out = ''
  354. shell.separate_out2 = ''
  355. ptformatter.pprint = False
  356. disp_formatter.active_types = ['text/plain']
  357. shell.magic('xmode Plain')
  358. else:
  359. # turn off
  360. shell.separate_in = dstore.rc_separate_in
  361. shell.separate_out = dstore.rc_separate_out
  362. shell.separate_out2 = dstore.rc_separate_out2
  363. ptformatter.pprint = dstore.rc_pprint
  364. disp_formatter.active_types = dstore.rc_active_types
  365. shell.magic('xmode ' + dstore.xmode)
  366. # mode here is the state before we switch; switch_doctest_mode takes
  367. # the mode we're switching to.
  368. shell.switch_doctest_mode(not mode)
  369. # Store new mode and inform
  370. dstore.mode = bool(not mode)
  371. mode_label = ['OFF','ON'][dstore.mode]
  372. print('Doctest mode is:', mode_label)
  373. @line_magic
  374. def gui(self, parameter_s=''):
  375. """Enable or disable IPython GUI event loop integration.
  376. %gui [GUINAME]
  377. This magic replaces IPython's threaded shells that were activated
  378. using the (pylab/wthread/etc.) command line flags. GUI toolkits
  379. can now be enabled at runtime and keyboard
  380. interrupts should work without any problems. The following toolkits
  381. are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
  382. %gui wx # enable wxPython event loop integration
  383. %gui qt4|qt # enable PyQt4 event loop integration
  384. %gui qt5 # enable PyQt5 event loop integration
  385. %gui gtk # enable PyGTK event loop integration
  386. %gui gtk3 # enable Gtk3 event loop integration
  387. %gui tk # enable Tk event loop integration
  388. %gui osx # enable Cocoa event loop integration
  389. # (requires %matplotlib 1.1)
  390. %gui # disable all event loop integration
  391. WARNING: after any of these has been called you can simply create
  392. an application object, but DO NOT start the event loop yourself, as
  393. we have already handled that.
  394. """
  395. opts, arg = self.parse_options(parameter_s, '')
  396. if arg=='': arg = None
  397. try:
  398. return self.shell.enable_gui(arg)
  399. except Exception as e:
  400. # print simple error message, rather than traceback if we can't
  401. # hook up the GUI
  402. error(str(e))
  403. @skip_doctest
  404. @line_magic
  405. def precision(self, s=''):
  406. """Set floating point precision for pretty printing.
  407. Can set either integer precision or a format string.
  408. If numpy has been imported and precision is an int,
  409. numpy display precision will also be set, via ``numpy.set_printoptions``.
  410. If no argument is given, defaults will be restored.
  411. Examples
  412. --------
  413. ::
  414. In [1]: from math import pi
  415. In [2]: %precision 3
  416. Out[2]: u'%.3f'
  417. In [3]: pi
  418. Out[3]: 3.142
  419. In [4]: %precision %i
  420. Out[4]: u'%i'
  421. In [5]: pi
  422. Out[5]: 3
  423. In [6]: %precision %e
  424. Out[6]: u'%e'
  425. In [7]: pi**10
  426. Out[7]: 9.364805e+04
  427. In [8]: %precision
  428. Out[8]: u'%r'
  429. In [9]: pi**10
  430. Out[9]: 93648.047476082982
  431. """
  432. ptformatter = self.shell.display_formatter.formatters['text/plain']
  433. ptformatter.float_precision = s
  434. return ptformatter.float_format
  435. @magic_arguments.magic_arguments()
  436. @magic_arguments.argument(
  437. '-e', '--export', action='store_true', default=False,
  438. help='Export IPython history as a notebook. The filename argument '
  439. 'is used to specify the notebook name and format. For example '
  440. 'a filename of notebook.ipynb will result in a notebook name '
  441. 'of "notebook" and a format of "json". Likewise using a ".py" '
  442. 'file extension will write the notebook as a Python script'
  443. )
  444. @magic_arguments.argument(
  445. 'filename', type=unicode_type,
  446. help='Notebook name or filename'
  447. )
  448. @line_magic
  449. def notebook(self, s):
  450. """Export and convert IPython notebooks.
  451. This function can export the current IPython history to a notebook file.
  452. For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
  453. To export the history to "foo.py" do "%notebook -e foo.py".
  454. """
  455. args = magic_arguments.parse_argstring(self.notebook, s)
  456. from nbformat import write, v4
  457. if args.export:
  458. cells = []
  459. hist = list(self.shell.history_manager.get_range())
  460. if(len(hist)<=1):
  461. raise ValueError('History is empty, cannot export')
  462. for session, execution_count, source in hist[:-1]:
  463. cells.append(v4.new_code_cell(
  464. execution_count=execution_count,
  465. source=source
  466. ))
  467. nb = v4.new_notebook(cells=cells)
  468. with io.open(args.filename, 'w', encoding='utf-8') as f:
  469. write(nb, f, version=4)