##// END OF EJS Templates
ENH: add pip and conda magics
Jake VanderPlas -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,101 b''
1 """Implementation of packaging-related magic functions.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2018 The IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 import os
12 import re
13 import shlex
14 import sys
15 from subprocess import Popen, PIPE
16
17 from IPython.core.magic import Magics, magics_class, line_magic
18
19
20 def _is_conda_environment():
21 """Return True if the current Python executable is in a conda env"""
22 # TODO: does this need to change on windows?
23 conda_history = os.path.join(sys.prefix, 'conda-meta', 'history')
24 return os.path.exists(conda_history)
25
26
27 def _get_conda_executable():
28 """Find the path to the conda executable"""
29 # Check if there is a conda executable in the same directory as the Python executable.
30 # This is the case within conda's root environment.
31 conda = os.path.join(os.path.dirname(sys.executable), 'conda')
32 if os.path.isfile(conda):
33 return conda
34
35 # Otherwise, attempt to extract the executable from conda history.
36 # This applies in any conda environment.
37 R = re.compile(r"^#\s*cmd:\s*(?P<command>.*conda)\s[create|install]")
38 for line in open(os.path.join(sys.prefix, 'conda-meta', 'history')):
39 match = R.match(line)
40 if match:
41 return match.groupdict()['command']
42
43 # Fallback: assume conda is available on the system path.
44 return "conda"
45
46
47 CONDA_COMMANDS_REQUIRING_PREFIX = {
48 'install', 'list', 'remove', 'uninstall', 'update', 'upgrade',
49 }
50 CONDA_COMMANDS_REQUIRING_YES = {
51 'install', 'remove', 'uninstall', 'update', 'upgrade',
52 }
53 CONDA_ENV_FLAGS = {'-p', '--prefix', '-n', '--name'}
54 CONDA_YES_FLAGS = {'-y', '--y'}
55
56
57 @magics_class
58 class PackagingMagics(Magics):
59 """Magics related to packaging & installation"""
60
61 @line_magic
62 def pip(self, line):
63 """Run the pip package manager within the current kernel.
64
65 Usage:
66 %pip install [pkgs]
67 """
68 self.shell.system(' '.join([sys.executable, '-m', 'pip', line]))
69
70 @line_magic
71 def conda(self, line):
72 """Run the conda package manager within the current kernel.
73
74 Usage:
75 %conda install [pkgs]
76 """
77 if not _is_conda_environment():
78 raise ValueError("The python kernel does not appear to be a conda environment. "
79 "Please use ``%pip install`` instead.")
80
81 conda = _get_conda_executable()
82 args = shlex.split(line)
83 command = args[0]
84 args = args[1:]
85 extra_args = []
86
87 # When the subprocess does not allow us to respond "yes" during the installation,
88 # we need to insert --yes in the argument list for some commands
89 stdin_disabled = getattr(self.shell, 'kernel', None) is not None
90 needs_yes = command in CONDA_COMMANDS_REQUIRING_YES
91 has_yes = set(args).intersection(CONDA_YES_FLAGS)
92 if stdin_disabled and needs_yes and not has_yes:
93 extra_args.append("--yes")
94
95 # Add --prefix to point conda installation to the current environment
96 needs_prefix = command in CONDA_COMMANDS_REQUIRING_PREFIX
97 has_prefix = set(args).intersection(CONDA_ENV_FLAGS)
98 if needs_prefix and not has_prefix:
99 extra_args.extend(["--prefix", sys.prefix])
100
101 self.shell.system(' '.join([conda, command] + extra_args + args)) No newline at end of file
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,41 +1,42 b''
1 """Implementation of all the magic functions built into IPython.
1 """Implementation of all the magic functions built into IPython.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from ..magic import Magics, magics_class
15 from ..magic import Magics, magics_class
16 from .auto import AutoMagics
16 from .auto import AutoMagics
17 from .basic import BasicMagics, AsyncMagics
17 from .basic import BasicMagics, AsyncMagics
18 from .code import CodeMagics, MacroToEdit
18 from .code import CodeMagics, MacroToEdit
19 from .config import ConfigMagics
19 from .config import ConfigMagics
20 from .display import DisplayMagics
20 from .display import DisplayMagics
21 from .execution import ExecutionMagics
21 from .execution import ExecutionMagics
22 from .extension import ExtensionMagics
22 from .extension import ExtensionMagics
23 from .history import HistoryMagics
23 from .history import HistoryMagics
24 from .logging import LoggingMagics
24 from .logging import LoggingMagics
25 from .namespace import NamespaceMagics
25 from .namespace import NamespaceMagics
26 from .osm import OSMagics
26 from .osm import OSMagics
27 from .packaging import PackagingMagics
27 from .pylab import PylabMagics
28 from .pylab import PylabMagics
28 from .script import ScriptMagics
29 from .script import ScriptMagics
29
30
30 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
31 # Magic implementation classes
32 # Magic implementation classes
32 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
33
34
34 @magics_class
35 @magics_class
35 class UserMagics(Magics):
36 class UserMagics(Magics):
36 """Placeholder for user-defined magics to be added at runtime.
37 """Placeholder for user-defined magics to be added at runtime.
37
38
38 All magics are eventually merged into a single namespace at runtime, but we
39 All magics are eventually merged into a single namespace at runtime, but we
39 use this class to isolate the magics defined dynamically by the user into
40 use this class to isolate the magics defined dynamically by the user into
40 their own class.
41 their own class.
41 """
42 """
@@ -1,671 +1,652 b''
1 """Implementation of basic magic functions."""
1 """Implementation of basic magic functions."""
2
2
3
3
4 import argparse
4 import argparse
5 from logging import error
5 from logging import error
6 import io
6 import io
7 from pprint import pformat
7 from pprint import pformat
8 import textwrap
8 import textwrap
9 import sys
9 import sys
10 from warnings import warn
10 from warnings import warn
11
11
12 from traitlets.utils.importstring import import_item
12 from traitlets.utils.importstring import import_item
13 from IPython.core import magic_arguments, page
13 from IPython.core import magic_arguments, page
14 from IPython.core.error import UsageError
14 from IPython.core.error import UsageError
15 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
15 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
16 from IPython.utils.text import format_screen, dedent, indent
16 from IPython.utils.text import format_screen, dedent, indent
17 from IPython.testing.skipdoctest import skip_doctest
17 from IPython.testing.skipdoctest import skip_doctest
18 from IPython.utils.ipstruct import Struct
18 from IPython.utils.ipstruct import Struct
19
19
20
20
21 class MagicsDisplay(object):
21 class MagicsDisplay(object):
22 def __init__(self, magics_manager, ignore=None):
22 def __init__(self, magics_manager, ignore=None):
23 self.ignore = ignore if ignore else []
23 self.ignore = ignore if ignore else []
24 self.magics_manager = magics_manager
24 self.magics_manager = magics_manager
25
25
26 def _lsmagic(self):
26 def _lsmagic(self):
27 """The main implementation of the %lsmagic"""
27 """The main implementation of the %lsmagic"""
28 mesc = magic_escapes['line']
28 mesc = magic_escapes['line']
29 cesc = magic_escapes['cell']
29 cesc = magic_escapes['cell']
30 mman = self.magics_manager
30 mman = self.magics_manager
31 magics = mman.lsmagic()
31 magics = mman.lsmagic()
32 out = ['Available line magics:',
32 out = ['Available line magics:',
33 mesc + (' '+mesc).join(sorted([m for m,v in magics['line'].items() if (v not in self.ignore)])),
33 mesc + (' '+mesc).join(sorted([m for m,v in magics['line'].items() if (v not in self.ignore)])),
34 '',
34 '',
35 'Available cell magics:',
35 'Available cell magics:',
36 cesc + (' '+cesc).join(sorted([m for m,v in magics['cell'].items() if (v not in self.ignore)])),
36 cesc + (' '+cesc).join(sorted([m for m,v in magics['cell'].items() if (v not in self.ignore)])),
37 '',
37 '',
38 mman.auto_status()]
38 mman.auto_status()]
39 return '\n'.join(out)
39 return '\n'.join(out)
40
40
41 def _repr_pretty_(self, p, cycle):
41 def _repr_pretty_(self, p, cycle):
42 p.text(self._lsmagic())
42 p.text(self._lsmagic())
43
43
44 def __str__(self):
44 def __str__(self):
45 return self._lsmagic()
45 return self._lsmagic()
46
46
47 def _jsonable(self):
47 def _jsonable(self):
48 """turn magics dict into jsonable dict of the same structure
48 """turn magics dict into jsonable dict of the same structure
49
49
50 replaces object instances with their class names as strings
50 replaces object instances with their class names as strings
51 """
51 """
52 magic_dict = {}
52 magic_dict = {}
53 mman = self.magics_manager
53 mman = self.magics_manager
54 magics = mman.lsmagic()
54 magics = mman.lsmagic()
55 for key, subdict in magics.items():
55 for key, subdict in magics.items():
56 d = {}
56 d = {}
57 magic_dict[key] = d
57 magic_dict[key] = d
58 for name, obj in subdict.items():
58 for name, obj in subdict.items():
59 try:
59 try:
60 classname = obj.__self__.__class__.__name__
60 classname = obj.__self__.__class__.__name__
61 except AttributeError:
61 except AttributeError:
62 classname = 'Other'
62 classname = 'Other'
63
63
64 d[name] = classname
64 d[name] = classname
65 return magic_dict
65 return magic_dict
66
66
67 def _repr_json_(self):
67 def _repr_json_(self):
68 return self._jsonable()
68 return self._jsonable()
69
69
70
70
71 @magics_class
71 @magics_class
72 class BasicMagics(Magics):
72 class BasicMagics(Magics):
73 """Magics that provide central IPython functionality.
73 """Magics that provide central IPython functionality.
74
74
75 These are various magics that don't fit into specific categories but that
75 These are various magics that don't fit into specific categories but that
76 are all part of the base 'IPython experience'."""
76 are all part of the base 'IPython experience'."""
77
77
78 @magic_arguments.magic_arguments()
78 @magic_arguments.magic_arguments()
79 @magic_arguments.argument(
79 @magic_arguments.argument(
80 '-l', '--line', action='store_true',
80 '-l', '--line', action='store_true',
81 help="""Create a line magic alias."""
81 help="""Create a line magic alias."""
82 )
82 )
83 @magic_arguments.argument(
83 @magic_arguments.argument(
84 '-c', '--cell', action='store_true',
84 '-c', '--cell', action='store_true',
85 help="""Create a cell magic alias."""
85 help="""Create a cell magic alias."""
86 )
86 )
87 @magic_arguments.argument(
87 @magic_arguments.argument(
88 'name',
88 'name',
89 help="""Name of the magic to be created."""
89 help="""Name of the magic to be created."""
90 )
90 )
91 @magic_arguments.argument(
91 @magic_arguments.argument(
92 'target',
92 'target',
93 help="""Name of the existing line or cell magic."""
93 help="""Name of the existing line or cell magic."""
94 )
94 )
95 @magic_arguments.argument(
95 @magic_arguments.argument(
96 '-p', '--params', default=None,
96 '-p', '--params', default=None,
97 help="""Parameters passed to the magic function."""
97 help="""Parameters passed to the magic function."""
98 )
98 )
99 @line_magic
99 @line_magic
100 def alias_magic(self, line=''):
100 def alias_magic(self, line=''):
101 """Create an alias for an existing line or cell magic.
101 """Create an alias for an existing line or cell magic.
102
102
103 Examples
103 Examples
104 --------
104 --------
105 ::
105 ::
106
106
107 In [1]: %alias_magic t timeit
107 In [1]: %alias_magic t timeit
108 Created `%t` as an alias for `%timeit`.
108 Created `%t` as an alias for `%timeit`.
109 Created `%%t` as an alias for `%%timeit`.
109 Created `%%t` as an alias for `%%timeit`.
110
110
111 In [2]: %t -n1 pass
111 In [2]: %t -n1 pass
112 1 loops, best of 3: 954 ns per loop
112 1 loops, best of 3: 954 ns per loop
113
113
114 In [3]: %%t -n1
114 In [3]: %%t -n1
115 ...: pass
115 ...: pass
116 ...:
116 ...:
117 1 loops, best of 3: 954 ns per loop
117 1 loops, best of 3: 954 ns per loop
118
118
119 In [4]: %alias_magic --cell whereami pwd
119 In [4]: %alias_magic --cell whereami pwd
120 UsageError: Cell magic function `%%pwd` not found.
120 UsageError: Cell magic function `%%pwd` not found.
121 In [5]: %alias_magic --line whereami pwd
121 In [5]: %alias_magic --line whereami pwd
122 Created `%whereami` as an alias for `%pwd`.
122 Created `%whereami` as an alias for `%pwd`.
123
123
124 In [6]: %whereami
124 In [6]: %whereami
125 Out[6]: u'/home/testuser'
125 Out[6]: u'/home/testuser'
126
126
127 In [7]: %alias_magic h history -p "-l 30" --line
127 In [7]: %alias_magic h history -p "-l 30" --line
128 Created `%h` as an alias for `%history -l 30`.
128 Created `%h` as an alias for `%history -l 30`.
129 """
129 """
130
130
131 args = magic_arguments.parse_argstring(self.alias_magic, line)
131 args = magic_arguments.parse_argstring(self.alias_magic, line)
132 shell = self.shell
132 shell = self.shell
133 mman = self.shell.magics_manager
133 mman = self.shell.magics_manager
134 escs = ''.join(magic_escapes.values())
134 escs = ''.join(magic_escapes.values())
135
135
136 target = args.target.lstrip(escs)
136 target = args.target.lstrip(escs)
137 name = args.name.lstrip(escs)
137 name = args.name.lstrip(escs)
138
138
139 params = args.params
139 params = args.params
140 if (params and
140 if (params and
141 ((params.startswith('"') and params.endswith('"'))
141 ((params.startswith('"') and params.endswith('"'))
142 or (params.startswith("'") and params.endswith("'")))):
142 or (params.startswith("'") and params.endswith("'")))):
143 params = params[1:-1]
143 params = params[1:-1]
144
144
145 # Find the requested magics.
145 # Find the requested magics.
146 m_line = shell.find_magic(target, 'line')
146 m_line = shell.find_magic(target, 'line')
147 m_cell = shell.find_magic(target, 'cell')
147 m_cell = shell.find_magic(target, 'cell')
148 if args.line and m_line is None:
148 if args.line and m_line is None:
149 raise UsageError('Line magic function `%s%s` not found.' %
149 raise UsageError('Line magic function `%s%s` not found.' %
150 (magic_escapes['line'], target))
150 (magic_escapes['line'], target))
151 if args.cell and m_cell is None:
151 if args.cell and m_cell is None:
152 raise UsageError('Cell magic function `%s%s` not found.' %
152 raise UsageError('Cell magic function `%s%s` not found.' %
153 (magic_escapes['cell'], target))
153 (magic_escapes['cell'], target))
154
154
155 # If --line and --cell are not specified, default to the ones
155 # If --line and --cell are not specified, default to the ones
156 # that are available.
156 # that are available.
157 if not args.line and not args.cell:
157 if not args.line and not args.cell:
158 if not m_line and not m_cell:
158 if not m_line and not m_cell:
159 raise UsageError(
159 raise UsageError(
160 'No line or cell magic with name `%s` found.' % target
160 'No line or cell magic with name `%s` found.' % target
161 )
161 )
162 args.line = bool(m_line)
162 args.line = bool(m_line)
163 args.cell = bool(m_cell)
163 args.cell = bool(m_cell)
164
164
165 params_str = "" if params is None else " " + params
165 params_str = "" if params is None else " " + params
166
166
167 if args.line:
167 if args.line:
168 mman.register_alias(name, target, 'line', params)
168 mman.register_alias(name, target, 'line', params)
169 print('Created `%s%s` as an alias for `%s%s%s`.' % (
169 print('Created `%s%s` as an alias for `%s%s%s`.' % (
170 magic_escapes['line'], name,
170 magic_escapes['line'], name,
171 magic_escapes['line'], target, params_str))
171 magic_escapes['line'], target, params_str))
172
172
173 if args.cell:
173 if args.cell:
174 mman.register_alias(name, target, 'cell', params)
174 mman.register_alias(name, target, 'cell', params)
175 print('Created `%s%s` as an alias for `%s%s%s`.' % (
175 print('Created `%s%s` as an alias for `%s%s%s`.' % (
176 magic_escapes['cell'], name,
176 magic_escapes['cell'], name,
177 magic_escapes['cell'], target, params_str))
177 magic_escapes['cell'], target, params_str))
178
178
179 @line_magic
179 @line_magic
180 def lsmagic(self, parameter_s=''):
180 def lsmagic(self, parameter_s=''):
181 """List currently available magic functions."""
181 """List currently available magic functions."""
182 return MagicsDisplay(self.shell.magics_manager, ignore=[self.pip])
182 return MagicsDisplay(self.shell.magics_manager, ignore=[self.pip])
183
183
184 def _magic_docs(self, brief=False, rest=False):
184 def _magic_docs(self, brief=False, rest=False):
185 """Return docstrings from magic functions."""
185 """Return docstrings from magic functions."""
186 mman = self.shell.magics_manager
186 mman = self.shell.magics_manager
187 docs = mman.lsmagic_docs(brief, missing='No documentation')
187 docs = mman.lsmagic_docs(brief, missing='No documentation')
188
188
189 if rest:
189 if rest:
190 format_string = '**%s%s**::\n\n%s\n\n'
190 format_string = '**%s%s**::\n\n%s\n\n'
191 else:
191 else:
192 format_string = '%s%s:\n%s\n'
192 format_string = '%s%s:\n%s\n'
193
193
194 return ''.join(
194 return ''.join(
195 [format_string % (magic_escapes['line'], fname,
195 [format_string % (magic_escapes['line'], fname,
196 indent(dedent(fndoc)))
196 indent(dedent(fndoc)))
197 for fname, fndoc in sorted(docs['line'].items())]
197 for fname, fndoc in sorted(docs['line'].items())]
198 +
198 +
199 [format_string % (magic_escapes['cell'], fname,
199 [format_string % (magic_escapes['cell'], fname,
200 indent(dedent(fndoc)))
200 indent(dedent(fndoc)))
201 for fname, fndoc in sorted(docs['cell'].items())]
201 for fname, fndoc in sorted(docs['cell'].items())]
202 )
202 )
203
203
204 @line_magic
204 @line_magic
205 def magic(self, parameter_s=''):
205 def magic(self, parameter_s=''):
206 """Print information about the magic function system.
206 """Print information about the magic function system.
207
207
208 Supported formats: -latex, -brief, -rest
208 Supported formats: -latex, -brief, -rest
209 """
209 """
210
210
211 mode = ''
211 mode = ''
212 try:
212 try:
213 mode = parameter_s.split()[0][1:]
213 mode = parameter_s.split()[0][1:]
214 except IndexError:
214 except IndexError:
215 pass
215 pass
216
216
217 brief = (mode == 'brief')
217 brief = (mode == 'brief')
218 rest = (mode == 'rest')
218 rest = (mode == 'rest')
219 magic_docs = self._magic_docs(brief, rest)
219 magic_docs = self._magic_docs(brief, rest)
220
220
221 if mode == 'latex':
221 if mode == 'latex':
222 print(self.format_latex(magic_docs))
222 print(self.format_latex(magic_docs))
223 return
223 return
224 else:
224 else:
225 magic_docs = format_screen(magic_docs)
225 magic_docs = format_screen(magic_docs)
226
226
227 out = ["""
227 out = ["""
228 IPython's 'magic' functions
228 IPython's 'magic' functions
229 ===========================
229 ===========================
230
230
231 The magic function system provides a series of functions which allow you to
231 The magic function system provides a series of functions which allow you to
232 control the behavior of IPython itself, plus a lot of system-type
232 control the behavior of IPython itself, plus a lot of system-type
233 features. There are two kinds of magics, line-oriented and cell-oriented.
233 features. There are two kinds of magics, line-oriented and cell-oriented.
234
234
235 Line magics are prefixed with the % character and work much like OS
235 Line magics are prefixed with the % character and work much like OS
236 command-line calls: they get as an argument the rest of the line, where
236 command-line calls: they get as an argument the rest of the line, where
237 arguments are passed without parentheses or quotes. For example, this will
237 arguments are passed without parentheses or quotes. For example, this will
238 time the given statement::
238 time the given statement::
239
239
240 %timeit range(1000)
240 %timeit range(1000)
241
241
242 Cell magics are prefixed with a double %%, and they are functions that get as
242 Cell magics are prefixed with a double %%, and they are functions that get as
243 an argument not only the rest of the line, but also the lines below it in a
243 an argument not only the rest of the line, but also the lines below it in a
244 separate argument. These magics are called with two arguments: the rest of the
244 separate argument. These magics are called with two arguments: the rest of the
245 call line and the body of the cell, consisting of the lines below the first.
245 call line and the body of the cell, consisting of the lines below the first.
246 For example::
246 For example::
247
247
248 %%timeit x = numpy.random.randn((100, 100))
248 %%timeit x = numpy.random.randn((100, 100))
249 numpy.linalg.svd(x)
249 numpy.linalg.svd(x)
250
250
251 will time the execution of the numpy svd routine, running the assignment of x
251 will time the execution of the numpy svd routine, running the assignment of x
252 as part of the setup phase, which is not timed.
252 as part of the setup phase, which is not timed.
253
253
254 In a line-oriented client (the terminal or Qt console IPython), starting a new
254 In a line-oriented client (the terminal or Qt console IPython), starting a new
255 input with %% will automatically enter cell mode, and IPython will continue
255 input with %% will automatically enter cell mode, and IPython will continue
256 reading input until a blank line is given. In the notebook, simply type the
256 reading input until a blank line is given. In the notebook, simply type the
257 whole cell as one entity, but keep in mind that the %% escape can only be at
257 whole cell as one entity, but keep in mind that the %% escape can only be at
258 the very start of the cell.
258 the very start of the cell.
259
259
260 NOTE: If you have 'automagic' enabled (via the command line option or with the
260 NOTE: If you have 'automagic' enabled (via the command line option or with the
261 %automagic function), you don't need to type in the % explicitly for line
261 %automagic function), you don't need to type in the % explicitly for line
262 magics; cell magics always require an explicit '%%' escape. By default,
262 magics; cell magics always require an explicit '%%' escape. By default,
263 IPython ships with automagic on, so you should only rarely need the % escape.
263 IPython ships with automagic on, so you should only rarely need the % escape.
264
264
265 Example: typing '%cd mydir' (without the quotes) changes your working directory
265 Example: typing '%cd mydir' (without the quotes) changes your working directory
266 to 'mydir', if it exists.
266 to 'mydir', if it exists.
267
267
268 For a list of the available magic functions, use %lsmagic. For a description
268 For a list of the available magic functions, use %lsmagic. For a description
269 of any of them, type %magic_name?, e.g. '%cd?'.
269 of any of them, type %magic_name?, e.g. '%cd?'.
270
270
271 Currently the magic system has the following functions:""",
271 Currently the magic system has the following functions:""",
272 magic_docs,
272 magic_docs,
273 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
273 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
274 str(self.lsmagic()),
274 str(self.lsmagic()),
275 ]
275 ]
276 page.page('\n'.join(out))
276 page.page('\n'.join(out))
277
277
278
278
279 @line_magic
279 @line_magic
280 def page(self, parameter_s=''):
280 def page(self, parameter_s=''):
281 """Pretty print the object and display it through a pager.
281 """Pretty print the object and display it through a pager.
282
282
283 %page [options] OBJECT
283 %page [options] OBJECT
284
284
285 If no object is given, use _ (last output).
285 If no object is given, use _ (last output).
286
286
287 Options:
287 Options:
288
288
289 -r: page str(object), don't pretty-print it."""
289 -r: page str(object), don't pretty-print it."""
290
290
291 # After a function contributed by Olivier Aubert, slightly modified.
291 # After a function contributed by Olivier Aubert, slightly modified.
292
292
293 # Process options/args
293 # Process options/args
294 opts, args = self.parse_options(parameter_s, 'r')
294 opts, args = self.parse_options(parameter_s, 'r')
295 raw = 'r' in opts
295 raw = 'r' in opts
296
296
297 oname = args and args or '_'
297 oname = args and args or '_'
298 info = self.shell._ofind(oname)
298 info = self.shell._ofind(oname)
299 if info['found']:
299 if info['found']:
300 txt = (raw and str or pformat)( info['obj'] )
300 txt = (raw and str or pformat)( info['obj'] )
301 page.page(txt)
301 page.page(txt)
302 else:
302 else:
303 print('Object `%s` not found' % oname)
303 print('Object `%s` not found' % oname)
304
304
305 @line_magic
305 @line_magic
306 def pprint(self, parameter_s=''):
306 def pprint(self, parameter_s=''):
307 """Toggle pretty printing on/off."""
307 """Toggle pretty printing on/off."""
308 ptformatter = self.shell.display_formatter.formatters['text/plain']
308 ptformatter = self.shell.display_formatter.formatters['text/plain']
309 ptformatter.pprint = bool(1 - ptformatter.pprint)
309 ptformatter.pprint = bool(1 - ptformatter.pprint)
310 print('Pretty printing has been turned',
310 print('Pretty printing has been turned',
311 ['OFF','ON'][ptformatter.pprint])
311 ['OFF','ON'][ptformatter.pprint])
312
312
313 @line_magic
313 @line_magic
314 def colors(self, parameter_s=''):
314 def colors(self, parameter_s=''):
315 """Switch color scheme for prompts, info system and exception handlers.
315 """Switch color scheme for prompts, info system and exception handlers.
316
316
317 Currently implemented schemes: NoColor, Linux, LightBG.
317 Currently implemented schemes: NoColor, Linux, LightBG.
318
318
319 Color scheme names are not case-sensitive.
319 Color scheme names are not case-sensitive.
320
320
321 Examples
321 Examples
322 --------
322 --------
323 To get a plain black and white terminal::
323 To get a plain black and white terminal::
324
324
325 %colors nocolor
325 %colors nocolor
326 """
326 """
327 def color_switch_err(name):
327 def color_switch_err(name):
328 warn('Error changing %s color schemes.\n%s' %
328 warn('Error changing %s color schemes.\n%s' %
329 (name, sys.exc_info()[1]), stacklevel=2)
329 (name, sys.exc_info()[1]), stacklevel=2)
330
330
331
331
332 new_scheme = parameter_s.strip()
332 new_scheme = parameter_s.strip()
333 if not new_scheme:
333 if not new_scheme:
334 raise UsageError(
334 raise UsageError(
335 "%colors: you must specify a color scheme. See '%colors?'")
335 "%colors: you must specify a color scheme. See '%colors?'")
336 # local shortcut
336 # local shortcut
337 shell = self.shell
337 shell = self.shell
338
338
339 # Set shell colour scheme
339 # Set shell colour scheme
340 try:
340 try:
341 shell.colors = new_scheme
341 shell.colors = new_scheme
342 shell.refresh_style()
342 shell.refresh_style()
343 except:
343 except:
344 color_switch_err('shell')
344 color_switch_err('shell')
345
345
346 # Set exception colors
346 # Set exception colors
347 try:
347 try:
348 shell.InteractiveTB.set_colors(scheme = new_scheme)
348 shell.InteractiveTB.set_colors(scheme = new_scheme)
349 shell.SyntaxTB.set_colors(scheme = new_scheme)
349 shell.SyntaxTB.set_colors(scheme = new_scheme)
350 except:
350 except:
351 color_switch_err('exception')
351 color_switch_err('exception')
352
352
353 # Set info (for 'object?') colors
353 # Set info (for 'object?') colors
354 if shell.color_info:
354 if shell.color_info:
355 try:
355 try:
356 shell.inspector.set_active_scheme(new_scheme)
356 shell.inspector.set_active_scheme(new_scheme)
357 except:
357 except:
358 color_switch_err('object inspector')
358 color_switch_err('object inspector')
359 else:
359 else:
360 shell.inspector.set_active_scheme('NoColor')
360 shell.inspector.set_active_scheme('NoColor')
361
361
362 @line_magic
362 @line_magic
363 def xmode(self, parameter_s=''):
363 def xmode(self, parameter_s=''):
364 """Switch modes for the exception handlers.
364 """Switch modes for the exception handlers.
365
365
366 Valid modes: Plain, Context, Verbose, and Minimal.
366 Valid modes: Plain, Context, Verbose, and Minimal.
367
367
368 If called without arguments, acts as a toggle."""
368 If called without arguments, acts as a toggle."""
369
369
370 def xmode_switch_err(name):
370 def xmode_switch_err(name):
371 warn('Error changing %s exception modes.\n%s' %
371 warn('Error changing %s exception modes.\n%s' %
372 (name,sys.exc_info()[1]))
372 (name,sys.exc_info()[1]))
373
373
374 shell = self.shell
374 shell = self.shell
375 new_mode = parameter_s.strip().capitalize()
375 new_mode = parameter_s.strip().capitalize()
376 try:
376 try:
377 shell.InteractiveTB.set_mode(mode=new_mode)
377 shell.InteractiveTB.set_mode(mode=new_mode)
378 print('Exception reporting mode:',shell.InteractiveTB.mode)
378 print('Exception reporting mode:',shell.InteractiveTB.mode)
379 except:
379 except:
380 xmode_switch_err('user')
380 xmode_switch_err('user')
381
381
382
383
384 @line_magic
385 def pip(self, args=''):
386 """
387 Intercept usage of ``pip`` in IPython and direct user to run command outside of IPython.
388 """
389 print(textwrap.dedent('''
390 The following command must be run outside of the IPython shell:
391
392 $ pip {args}
393
394 The Python package manager (pip) can only be used from outside of IPython.
395 Please reissue the `pip` command in a separate terminal or command prompt.
396
397 See the Python documentation for more information on how to install packages:
398
399 https://docs.python.org/3/installing/'''.format(args=args)))
400
401 @line_magic
382 @line_magic
402 def quickref(self, arg):
383 def quickref(self, arg):
403 """ Show a quick reference sheet """
384 """ Show a quick reference sheet """
404 from IPython.core.usage import quick_reference
385 from IPython.core.usage import quick_reference
405 qr = quick_reference + self._magic_docs(brief=True)
386 qr = quick_reference + self._magic_docs(brief=True)
406 page.page(qr)
387 page.page(qr)
407
388
408 @line_magic
389 @line_magic
409 def doctest_mode(self, parameter_s=''):
390 def doctest_mode(self, parameter_s=''):
410 """Toggle doctest mode on and off.
391 """Toggle doctest mode on and off.
411
392
412 This mode is intended to make IPython behave as much as possible like a
393 This mode is intended to make IPython behave as much as possible like a
413 plain Python shell, from the perspective of how its prompts, exceptions
394 plain Python shell, from the perspective of how its prompts, exceptions
414 and output look. This makes it easy to copy and paste parts of a
395 and output look. This makes it easy to copy and paste parts of a
415 session into doctests. It does so by:
396 session into doctests. It does so by:
416
397
417 - Changing the prompts to the classic ``>>>`` ones.
398 - Changing the prompts to the classic ``>>>`` ones.
418 - Changing the exception reporting mode to 'Plain'.
399 - Changing the exception reporting mode to 'Plain'.
419 - Disabling pretty-printing of output.
400 - Disabling pretty-printing of output.
420
401
421 Note that IPython also supports the pasting of code snippets that have
402 Note that IPython also supports the pasting of code snippets that have
422 leading '>>>' and '...' prompts in them. This means that you can paste
403 leading '>>>' and '...' prompts in them. This means that you can paste
423 doctests from files or docstrings (even if they have leading
404 doctests from files or docstrings (even if they have leading
424 whitespace), and the code will execute correctly. You can then use
405 whitespace), and the code will execute correctly. You can then use
425 '%history -t' to see the translated history; this will give you the
406 '%history -t' to see the translated history; this will give you the
426 input after removal of all the leading prompts and whitespace, which
407 input after removal of all the leading prompts and whitespace, which
427 can be pasted back into an editor.
408 can be pasted back into an editor.
428
409
429 With these features, you can switch into this mode easily whenever you
410 With these features, you can switch into this mode easily whenever you
430 need to do testing and changes to doctests, without having to leave
411 need to do testing and changes to doctests, without having to leave
431 your existing IPython session.
412 your existing IPython session.
432 """
413 """
433
414
434 # Shorthands
415 # Shorthands
435 shell = self.shell
416 shell = self.shell
436 meta = shell.meta
417 meta = shell.meta
437 disp_formatter = self.shell.display_formatter
418 disp_formatter = self.shell.display_formatter
438 ptformatter = disp_formatter.formatters['text/plain']
419 ptformatter = disp_formatter.formatters['text/plain']
439 # dstore is a data store kept in the instance metadata bag to track any
420 # dstore is a data store kept in the instance metadata bag to track any
440 # changes we make, so we can undo them later.
421 # changes we make, so we can undo them later.
441 dstore = meta.setdefault('doctest_mode',Struct())
422 dstore = meta.setdefault('doctest_mode',Struct())
442 save_dstore = dstore.setdefault
423 save_dstore = dstore.setdefault
443
424
444 # save a few values we'll need to recover later
425 # save a few values we'll need to recover later
445 mode = save_dstore('mode',False)
426 mode = save_dstore('mode',False)
446 save_dstore('rc_pprint',ptformatter.pprint)
427 save_dstore('rc_pprint',ptformatter.pprint)
447 save_dstore('xmode',shell.InteractiveTB.mode)
428 save_dstore('xmode',shell.InteractiveTB.mode)
448 save_dstore('rc_separate_out',shell.separate_out)
429 save_dstore('rc_separate_out',shell.separate_out)
449 save_dstore('rc_separate_out2',shell.separate_out2)
430 save_dstore('rc_separate_out2',shell.separate_out2)
450 save_dstore('rc_separate_in',shell.separate_in)
431 save_dstore('rc_separate_in',shell.separate_in)
451 save_dstore('rc_active_types',disp_formatter.active_types)
432 save_dstore('rc_active_types',disp_formatter.active_types)
452
433
453 if not mode:
434 if not mode:
454 # turn on
435 # turn on
455
436
456 # Prompt separators like plain python
437 # Prompt separators like plain python
457 shell.separate_in = ''
438 shell.separate_in = ''
458 shell.separate_out = ''
439 shell.separate_out = ''
459 shell.separate_out2 = ''
440 shell.separate_out2 = ''
460
441
461
442
462 ptformatter.pprint = False
443 ptformatter.pprint = False
463 disp_formatter.active_types = ['text/plain']
444 disp_formatter.active_types = ['text/plain']
464
445
465 shell.magic('xmode Plain')
446 shell.magic('xmode Plain')
466 else:
447 else:
467 # turn off
448 # turn off
468 shell.separate_in = dstore.rc_separate_in
449 shell.separate_in = dstore.rc_separate_in
469
450
470 shell.separate_out = dstore.rc_separate_out
451 shell.separate_out = dstore.rc_separate_out
471 shell.separate_out2 = dstore.rc_separate_out2
452 shell.separate_out2 = dstore.rc_separate_out2
472
453
473 ptformatter.pprint = dstore.rc_pprint
454 ptformatter.pprint = dstore.rc_pprint
474 disp_formatter.active_types = dstore.rc_active_types
455 disp_formatter.active_types = dstore.rc_active_types
475
456
476 shell.magic('xmode ' + dstore.xmode)
457 shell.magic('xmode ' + dstore.xmode)
477
458
478 # mode here is the state before we switch; switch_doctest_mode takes
459 # mode here is the state before we switch; switch_doctest_mode takes
479 # the mode we're switching to.
460 # the mode we're switching to.
480 shell.switch_doctest_mode(not mode)
461 shell.switch_doctest_mode(not mode)
481
462
482 # Store new mode and inform
463 # Store new mode and inform
483 dstore.mode = bool(not mode)
464 dstore.mode = bool(not mode)
484 mode_label = ['OFF','ON'][dstore.mode]
465 mode_label = ['OFF','ON'][dstore.mode]
485 print('Doctest mode is:', mode_label)
466 print('Doctest mode is:', mode_label)
486
467
487 @line_magic
468 @line_magic
488 def gui(self, parameter_s=''):
469 def gui(self, parameter_s=''):
489 """Enable or disable IPython GUI event loop integration.
470 """Enable or disable IPython GUI event loop integration.
490
471
491 %gui [GUINAME]
472 %gui [GUINAME]
492
473
493 This magic replaces IPython's threaded shells that were activated
474 This magic replaces IPython's threaded shells that were activated
494 using the (pylab/wthread/etc.) command line flags. GUI toolkits
475 using the (pylab/wthread/etc.) command line flags. GUI toolkits
495 can now be enabled at runtime and keyboard
476 can now be enabled at runtime and keyboard
496 interrupts should work without any problems. The following toolkits
477 interrupts should work without any problems. The following toolkits
497 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
478 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
498
479
499 %gui wx # enable wxPython event loop integration
480 %gui wx # enable wxPython event loop integration
500 %gui qt4|qt # enable PyQt4 event loop integration
481 %gui qt4|qt # enable PyQt4 event loop integration
501 %gui qt5 # enable PyQt5 event loop integration
482 %gui qt5 # enable PyQt5 event loop integration
502 %gui gtk # enable PyGTK event loop integration
483 %gui gtk # enable PyGTK event loop integration
503 %gui gtk3 # enable Gtk3 event loop integration
484 %gui gtk3 # enable Gtk3 event loop integration
504 %gui tk # enable Tk event loop integration
485 %gui tk # enable Tk event loop integration
505 %gui osx # enable Cocoa event loop integration
486 %gui osx # enable Cocoa event loop integration
506 # (requires %matplotlib 1.1)
487 # (requires %matplotlib 1.1)
507 %gui # disable all event loop integration
488 %gui # disable all event loop integration
508
489
509 WARNING: after any of these has been called you can simply create
490 WARNING: after any of these has been called you can simply create
510 an application object, but DO NOT start the event loop yourself, as
491 an application object, but DO NOT start the event loop yourself, as
511 we have already handled that.
492 we have already handled that.
512 """
493 """
513 opts, arg = self.parse_options(parameter_s, '')
494 opts, arg = self.parse_options(parameter_s, '')
514 if arg=='': arg = None
495 if arg=='': arg = None
515 try:
496 try:
516 return self.shell.enable_gui(arg)
497 return self.shell.enable_gui(arg)
517 except Exception as e:
498 except Exception as e:
518 # print simple error message, rather than traceback if we can't
499 # print simple error message, rather than traceback if we can't
519 # hook up the GUI
500 # hook up the GUI
520 error(str(e))
501 error(str(e))
521
502
522 @skip_doctest
503 @skip_doctest
523 @line_magic
504 @line_magic
524 def precision(self, s=''):
505 def precision(self, s=''):
525 """Set floating point precision for pretty printing.
506 """Set floating point precision for pretty printing.
526
507
527 Can set either integer precision or a format string.
508 Can set either integer precision or a format string.
528
509
529 If numpy has been imported and precision is an int,
510 If numpy has been imported and precision is an int,
530 numpy display precision will also be set, via ``numpy.set_printoptions``.
511 numpy display precision will also be set, via ``numpy.set_printoptions``.
531
512
532 If no argument is given, defaults will be restored.
513 If no argument is given, defaults will be restored.
533
514
534 Examples
515 Examples
535 --------
516 --------
536 ::
517 ::
537
518
538 In [1]: from math import pi
519 In [1]: from math import pi
539
520
540 In [2]: %precision 3
521 In [2]: %precision 3
541 Out[2]: u'%.3f'
522 Out[2]: u'%.3f'
542
523
543 In [3]: pi
524 In [3]: pi
544 Out[3]: 3.142
525 Out[3]: 3.142
545
526
546 In [4]: %precision %i
527 In [4]: %precision %i
547 Out[4]: u'%i'
528 Out[4]: u'%i'
548
529
549 In [5]: pi
530 In [5]: pi
550 Out[5]: 3
531 Out[5]: 3
551
532
552 In [6]: %precision %e
533 In [6]: %precision %e
553 Out[6]: u'%e'
534 Out[6]: u'%e'
554
535
555 In [7]: pi**10
536 In [7]: pi**10
556 Out[7]: 9.364805e+04
537 Out[7]: 9.364805e+04
557
538
558 In [8]: %precision
539 In [8]: %precision
559 Out[8]: u'%r'
540 Out[8]: u'%r'
560
541
561 In [9]: pi**10
542 In [9]: pi**10
562 Out[9]: 93648.047476082982
543 Out[9]: 93648.047476082982
563 """
544 """
564 ptformatter = self.shell.display_formatter.formatters['text/plain']
545 ptformatter = self.shell.display_formatter.formatters['text/plain']
565 ptformatter.float_precision = s
546 ptformatter.float_precision = s
566 return ptformatter.float_format
547 return ptformatter.float_format
567
548
568 @magic_arguments.magic_arguments()
549 @magic_arguments.magic_arguments()
569 @magic_arguments.argument(
550 @magic_arguments.argument(
570 '-e', '--export', action='store_true', default=False,
551 '-e', '--export', action='store_true', default=False,
571 help=argparse.SUPPRESS
552 help=argparse.SUPPRESS
572 )
553 )
573 @magic_arguments.argument(
554 @magic_arguments.argument(
574 'filename', type=str,
555 'filename', type=str,
575 help='Notebook name or filename'
556 help='Notebook name or filename'
576 )
557 )
577 @line_magic
558 @line_magic
578 def notebook(self, s):
559 def notebook(self, s):
579 """Export and convert IPython notebooks.
560 """Export and convert IPython notebooks.
580
561
581 This function can export the current IPython history to a notebook file.
562 This function can export the current IPython history to a notebook file.
582 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
563 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
583
564
584 The -e or --export flag is deprecated in IPython 5.2, and will be
565 The -e or --export flag is deprecated in IPython 5.2, and will be
585 removed in the future.
566 removed in the future.
586 """
567 """
587 args = magic_arguments.parse_argstring(self.notebook, s)
568 args = magic_arguments.parse_argstring(self.notebook, s)
588
569
589 from nbformat import write, v4
570 from nbformat import write, v4
590
571
591 cells = []
572 cells = []
592 hist = list(self.shell.history_manager.get_range())
573 hist = list(self.shell.history_manager.get_range())
593 if(len(hist)<=1):
574 if(len(hist)<=1):
594 raise ValueError('History is empty, cannot export')
575 raise ValueError('History is empty, cannot export')
595 for session, execution_count, source in hist[:-1]:
576 for session, execution_count, source in hist[:-1]:
596 cells.append(v4.new_code_cell(
577 cells.append(v4.new_code_cell(
597 execution_count=execution_count,
578 execution_count=execution_count,
598 source=source
579 source=source
599 ))
580 ))
600 nb = v4.new_notebook(cells=cells)
581 nb = v4.new_notebook(cells=cells)
601 with io.open(args.filename, 'w', encoding='utf-8') as f:
582 with io.open(args.filename, 'w', encoding='utf-8') as f:
602 write(nb, f, version=4)
583 write(nb, f, version=4)
603
584
604 @magics_class
585 @magics_class
605 class AsyncMagics(BasicMagics):
586 class AsyncMagics(BasicMagics):
606
587
607 @line_magic
588 @line_magic
608 def autoawait(self, parameter_s):
589 def autoawait(self, parameter_s):
609 """
590 """
610 Allow to change the status of the autoawait option.
591 Allow to change the status of the autoawait option.
611
592
612 This allow you to set a specific asynchronous code runner.
593 This allow you to set a specific asynchronous code runner.
613
594
614 If no value is passed, print the currently used asynchronous integration
595 If no value is passed, print the currently used asynchronous integration
615 and whether it is activated.
596 and whether it is activated.
616
597
617 It can take a number of value evaluated in the following order:
598 It can take a number of value evaluated in the following order:
618
599
619 - False/false/off deactivate autoawait integration
600 - False/false/off deactivate autoawait integration
620 - True/true/on activate autoawait integration using configured default
601 - True/true/on activate autoawait integration using configured default
621 loop
602 loop
622 - asyncio/curio/trio activate autoawait integration and use integration
603 - asyncio/curio/trio activate autoawait integration and use integration
623 with said library.
604 with said library.
624
605
625 - `sync` turn on the pseudo-sync integration (mostly used for
606 - `sync` turn on the pseudo-sync integration (mostly used for
626 `IPython.embed()` which does not run IPython with a real eventloop and
607 `IPython.embed()` which does not run IPython with a real eventloop and
627 deactivate running asynchronous code. Turning on Asynchronous code with
608 deactivate running asynchronous code. Turning on Asynchronous code with
628 the pseudo sync loop is undefined behavior and may lead IPython to crash.
609 the pseudo sync loop is undefined behavior and may lead IPython to crash.
629
610
630 If the passed parameter does not match any of the above and is a python
611 If the passed parameter does not match any of the above and is a python
631 identifier, get said object from user namespace and set it as the
612 identifier, get said object from user namespace and set it as the
632 runner, and activate autoawait.
613 runner, and activate autoawait.
633
614
634 If the object is a fully qualified object name, attempt to import it and
615 If the object is a fully qualified object name, attempt to import it and
635 set it as the runner, and activate autoawait.
616 set it as the runner, and activate autoawait.
636
617
637
618
638 The exact behavior of autoawait is experimental and subject to change
619 The exact behavior of autoawait is experimental and subject to change
639 across version of IPython and Python.
620 across version of IPython and Python.
640 """
621 """
641
622
642 param = parameter_s.strip()
623 param = parameter_s.strip()
643 d = {True: "on", False: "off"}
624 d = {True: "on", False: "off"}
644
625
645 if not param:
626 if not param:
646 print("IPython autoawait is `{}`, and set to use `{}`".format(
627 print("IPython autoawait is `{}`, and set to use `{}`".format(
647 d[self.shell.autoawait],
628 d[self.shell.autoawait],
648 self.shell.loop_runner
629 self.shell.loop_runner
649 ))
630 ))
650 return None
631 return None
651
632
652 if param.lower() in ('false', 'off'):
633 if param.lower() in ('false', 'off'):
653 self.shell.autoawait = False
634 self.shell.autoawait = False
654 return None
635 return None
655 if param.lower() in ('true', 'on'):
636 if param.lower() in ('true', 'on'):
656 self.shell.autoawait = True
637 self.shell.autoawait = True
657 return None
638 return None
658
639
659 if param in self.shell.loop_runner_map:
640 if param in self.shell.loop_runner_map:
660 self.shell.loop_runner, self.shell.autoawait = self.shell.loop_runner_map[param]
641 self.shell.loop_runner, self.shell.autoawait = self.shell.loop_runner_map[param]
661 return None
642 return None
662
643
663 if param in self.shell.user_ns :
644 if param in self.shell.user_ns :
664 self.shell.loop_runner = self.shell.user_ns[param]
645 self.shell.loop_runner = self.shell.user_ns[param]
665 self.shell.autoawait = True
646 self.shell.autoawait = True
666 return None
647 return None
667
648
668 runner = import_item(param)
649 runner = import_item(param)
669
650
670 self.shell.loop_runner = runner
651 self.shell.loop_runner = runner
671 self.shell.autoawait = True
652 self.shell.autoawait = True
General Comments 0
You need to be logged in to leave comments. Login now