##// END OF EJS Templates
addressing linting issues
Aditya Sathe -
Show More
@@ -1,714 +1,717 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2008 The IPython Development Team
8 # Copyright (C) 2008 The IPython Development Team
9
9
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 import os
14 import os
15 import re
15 import re
16 import sys
16 import sys
17 from getopt import getopt, GetoptError
17 from getopt import getopt, GetoptError
18
18
19 from traitlets.config.configurable import Configurable
19 from traitlets.config.configurable import Configurable
20 from . import oinspect
20 from . import oinspect
21 from .error import UsageError
21 from .error import UsageError
22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
23 from decorator import decorator
23 from decorator import decorator
24 from ..utils.ipstruct import Struct
24 from ..utils.ipstruct import Struct
25 from ..utils.process import arg_split
25 from ..utils.process import arg_split
26 from ..utils.text import dedent
26 from ..utils.text import dedent
27 from traitlets import Bool, Dict, Instance, observe
27 from traitlets import Bool, Dict, Instance, observe
28 from logging import error
28 from logging import error
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Globals
31 # Globals
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 # A dict we'll use for each class that has magics, used as temporary storage to
34 # A dict we'll use for each class that has magics, used as temporary storage to
35 # pass information between the @line/cell_magic method decorators and the
35 # pass information between the @line/cell_magic method decorators and the
36 # @magics_class class decorator, because the method decorators have no
36 # @magics_class class decorator, because the method decorators have no
37 # access to the class when they run. See for more details:
37 # access to the class when they run. See for more details:
38 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
38 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
39
39
40 magics = dict(line={}, cell={})
40 magics = dict(line={}, cell={})
41
41
42 magic_kinds = ('line', 'cell')
42 magic_kinds = ('line', 'cell')
43 magic_spec = ('line', 'cell', 'line_cell')
43 magic_spec = ('line', 'cell', 'line_cell')
44 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
44 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Utility classes and functions
47 # Utility classes and functions
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class Bunch: pass
50 class Bunch: pass
51
51
52
52
53 def on_off(tag):
53 def on_off(tag):
54 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
54 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
55 return ['OFF','ON'][tag]
55 return ['OFF','ON'][tag]
56
56
57
57
58 def compress_dhist(dh):
58 def compress_dhist(dh):
59 """Compress a directory history into a new one with at most 20 entries.
59 """Compress a directory history into a new one with at most 20 entries.
60
60
61 Return a new list made from the first and last 10 elements of dhist after
61 Return a new list made from the first and last 10 elements of dhist after
62 removal of duplicates.
62 removal of duplicates.
63 """
63 """
64 head, tail = dh[:-10], dh[-10:]
64 head, tail = dh[:-10], dh[-10:]
65
65
66 newhead = []
66 newhead = []
67 done = set()
67 done = set()
68 for h in head:
68 for h in head:
69 if h in done:
69 if h in done:
70 continue
70 continue
71 newhead.append(h)
71 newhead.append(h)
72 done.add(h)
72 done.add(h)
73
73
74 return newhead + tail
74 return newhead + tail
75
75
76
76
77 def needs_local_scope(func):
77 def needs_local_scope(func):
78 """Decorator to mark magic functions which need to local scope to run."""
78 """Decorator to mark magic functions which need to local scope to run."""
79 func.needs_local_scope = True
79 func.needs_local_scope = True
80 return func
80 return func
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Class and method decorators for registering magics
83 # Class and method decorators for registering magics
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 def magics_class(cls):
86 def magics_class(cls):
87 """Class decorator for all subclasses of the main Magics class.
87 """Class decorator for all subclasses of the main Magics class.
88
88
89 Any class that subclasses Magics *must* also apply this decorator, to
89 Any class that subclasses Magics *must* also apply this decorator, to
90 ensure that all the methods that have been decorated as line/cell magics
90 ensure that all the methods that have been decorated as line/cell magics
91 get correctly registered in the class instance. This is necessary because
91 get correctly registered in the class instance. This is necessary because
92 when method decorators run, the class does not exist yet, so they
92 when method decorators run, the class does not exist yet, so they
93 temporarily store their information into a module global. Application of
93 temporarily store their information into a module global. Application of
94 this class decorator copies that global data to the class instance and
94 this class decorator copies that global data to the class instance and
95 clears the global.
95 clears the global.
96
96
97 Obviously, this mechanism is not thread-safe, which means that the
97 Obviously, this mechanism is not thread-safe, which means that the
98 *creation* of subclasses of Magic should only be done in a single-thread
98 *creation* of subclasses of Magic should only be done in a single-thread
99 context. Instantiation of the classes has no restrictions. Given that
99 context. Instantiation of the classes has no restrictions. Given that
100 these classes are typically created at IPython startup time and before user
100 these classes are typically created at IPython startup time and before user
101 application code becomes active, in practice this should not pose any
101 application code becomes active, in practice this should not pose any
102 problems.
102 problems.
103 """
103 """
104 cls.registered = True
104 cls.registered = True
105 cls.magics = dict(line = magics['line'],
105 cls.magics = dict(line = magics['line'],
106 cell = magics['cell'])
106 cell = magics['cell'])
107 magics['line'] = {}
107 magics['line'] = {}
108 magics['cell'] = {}
108 magics['cell'] = {}
109 return cls
109 return cls
110
110
111
111
112 def record_magic(dct, magic_kind, magic_name, func):
112 def record_magic(dct, magic_kind, magic_name, func):
113 """Utility function to store a function as a magic of a specific kind.
113 """Utility function to store a function as a magic of a specific kind.
114
114
115 Parameters
115 Parameters
116 ----------
116 ----------
117 dct : dict
117 dct : dict
118 A dictionary with 'line' and 'cell' subdicts.
118 A dictionary with 'line' and 'cell' subdicts.
119
119
120 magic_kind : str
120 magic_kind : str
121 Kind of magic to be stored.
121 Kind of magic to be stored.
122
122
123 magic_name : str
123 magic_name : str
124 Key to store the magic as.
124 Key to store the magic as.
125
125
126 func : function
126 func : function
127 Callable object to store.
127 Callable object to store.
128 """
128 """
129 if magic_kind == 'line_cell':
129 if magic_kind == 'line_cell':
130 dct['line'][magic_name] = dct['cell'][magic_name] = func
130 dct['line'][magic_name] = dct['cell'][magic_name] = func
131 else:
131 else:
132 dct[magic_kind][magic_name] = func
132 dct[magic_kind][magic_name] = func
133
133
134
134
135 def validate_type(magic_kind):
135 def validate_type(magic_kind):
136 """Ensure that the given magic_kind is valid.
136 """Ensure that the given magic_kind is valid.
137
137
138 Check that the given magic_kind is one of the accepted spec types (stored
138 Check that the given magic_kind is one of the accepted spec types (stored
139 in the global `magic_spec`), raise ValueError otherwise.
139 in the global `magic_spec`), raise ValueError otherwise.
140 """
140 """
141 if magic_kind not in magic_spec:
141 if magic_kind not in magic_spec:
142 raise ValueError('magic_kind must be one of %s, %s given' %
142 raise ValueError('magic_kind must be one of %s, %s given' %
143 magic_kinds, magic_kind)
143 magic_kinds, magic_kind)
144
144
145
145
146 # The docstrings for the decorator below will be fairly similar for the two
146 # The docstrings for the decorator below will be fairly similar for the two
147 # types (method and function), so we generate them here once and reuse the
147 # types (method and function), so we generate them here once and reuse the
148 # templates below.
148 # templates below.
149 _docstring_template = \
149 _docstring_template = \
150 """Decorate the given {0} as {1} magic.
150 """Decorate the given {0} as {1} magic.
151
151
152 The decorator can be used with or without arguments, as follows.
152 The decorator can be used with or without arguments, as follows.
153
153
154 i) without arguments: it will create a {1} magic named as the {0} being
154 i) without arguments: it will create a {1} magic named as the {0} being
155 decorated::
155 decorated::
156
156
157 @deco
157 @deco
158 def foo(...)
158 def foo(...)
159
159
160 will create a {1} magic named `foo`.
160 will create a {1} magic named `foo`.
161
161
162 ii) with one string argument: which will be used as the actual name of the
162 ii) with one string argument: which will be used as the actual name of the
163 resulting magic::
163 resulting magic::
164
164
165 @deco('bar')
165 @deco('bar')
166 def foo(...)
166 def foo(...)
167
167
168 will create a {1} magic named `bar`.
168 will create a {1} magic named `bar`.
169
169
170 To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
170 To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
171 """
171 """
172
172
173 # These two are decorator factories. While they are conceptually very similar,
173 # These two are decorator factories. While they are conceptually very similar,
174 # there are enough differences in the details that it's simpler to have them
174 # there are enough differences in the details that it's simpler to have them
175 # written as completely standalone functions rather than trying to share code
175 # written as completely standalone functions rather than trying to share code
176 # and make a single one with convoluted logic.
176 # and make a single one with convoluted logic.
177
177
178 def _method_magic_marker(magic_kind):
178 def _method_magic_marker(magic_kind):
179 """Decorator factory for methods in Magics subclasses.
179 """Decorator factory for methods in Magics subclasses.
180 """
180 """
181
181
182 validate_type(magic_kind)
182 validate_type(magic_kind)
183
183
184 # This is a closure to capture the magic_kind. We could also use a class,
184 # This is a closure to capture the magic_kind. We could also use a class,
185 # but it's overkill for just that one bit of state.
185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
186 def magic_deco(arg):
187 call = lambda f, *a, **k: f(*a, **k)
187 call = lambda f, *a, **k: f(*a, **k)
188
188
189 if callable(arg):
189 if callable(arg):
190 # "Naked" decorator call (just @foo, no args)
190 # "Naked" decorator call (just @foo, no args)
191 func = arg
191 func = arg
192 name = func.__name__
192 name = func.__name__
193 retval = decorator(call, func)
193 retval = decorator(call, func)
194 record_magic(magics, magic_kind, name, name)
194 record_magic(magics, magic_kind, name, name)
195 elif isinstance(arg, str):
195 elif isinstance(arg, str):
196 # Decorator called with arguments (@foo('bar'))
196 # Decorator called with arguments (@foo('bar'))
197 name = arg
197 name = arg
198 def mark(func, *a, **kw):
198 def mark(func, *a, **kw):
199 record_magic(magics, magic_kind, name, func.__name__)
199 record_magic(magics, magic_kind, name, func.__name__)
200 return decorator(call, func)
200 return decorator(call, func)
201 retval = mark
201 retval = mark
202 else:
202 else:
203 raise TypeError("Decorator can only be called with "
203 raise TypeError("Decorator can only be called with "
204 "string or function")
204 "string or function")
205 return retval
205 return retval
206
206
207 # Ensure the resulting decorator has a usable docstring
207 # Ensure the resulting decorator has a usable docstring
208 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
208 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
209 return magic_deco
209 return magic_deco
210
210
211
211
212 def _function_magic_marker(magic_kind):
212 def _function_magic_marker(magic_kind):
213 """Decorator factory for standalone functions.
213 """Decorator factory for standalone functions.
214 """
214 """
215 validate_type(magic_kind)
215 validate_type(magic_kind)
216
216
217 # This is a closure to capture the magic_kind. We could also use a class,
217 # This is a closure to capture the magic_kind. We could also use a class,
218 # but it's overkill for just that one bit of state.
218 # but it's overkill for just that one bit of state.
219 def magic_deco(arg):
219 def magic_deco(arg):
220 call = lambda f, *a, **k: f(*a, **k)
220 call = lambda f, *a, **k: f(*a, **k)
221
221
222 # Find get_ipython() in the caller's namespace
222 # Find get_ipython() in the caller's namespace
223 caller = sys._getframe(1)
223 caller = sys._getframe(1)
224 for ns in ['f_locals', 'f_globals', 'f_builtins']:
224 for ns in ['f_locals', 'f_globals', 'f_builtins']:
225 get_ipython = getattr(caller, ns).get('get_ipython')
225 get_ipython = getattr(caller, ns).get('get_ipython')
226 if get_ipython is not None:
226 if get_ipython is not None:
227 break
227 break
228 else:
228 else:
229 raise NameError('Decorator can only run in context where '
229 raise NameError('Decorator can only run in context where '
230 '`get_ipython` exists')
230 '`get_ipython` exists')
231
231
232 ip = get_ipython()
232 ip = get_ipython()
233
233
234 if callable(arg):
234 if callable(arg):
235 # "Naked" decorator call (just @foo, no args)
235 # "Naked" decorator call (just @foo, no args)
236 func = arg
236 func = arg
237 name = func.__name__
237 name = func.__name__
238 ip.register_magic_function(func, magic_kind, name)
238 ip.register_magic_function(func, magic_kind, name)
239 retval = decorator(call, func)
239 retval = decorator(call, func)
240 elif isinstance(arg, str):
240 elif isinstance(arg, str):
241 # Decorator called with arguments (@foo('bar'))
241 # Decorator called with arguments (@foo('bar'))
242 name = arg
242 name = arg
243 def mark(func, *a, **kw):
243 def mark(func, *a, **kw):
244 ip.register_magic_function(func, magic_kind, name)
244 ip.register_magic_function(func, magic_kind, name)
245 return decorator(call, func)
245 return decorator(call, func)
246 retval = mark
246 retval = mark
247 else:
247 else:
248 raise TypeError("Decorator can only be called with "
248 raise TypeError("Decorator can only be called with "
249 "string or function")
249 "string or function")
250 return retval
250 return retval
251
251
252 # Ensure the resulting decorator has a usable docstring
252 # Ensure the resulting decorator has a usable docstring
253 ds = _docstring_template.format('function', magic_kind)
253 ds = _docstring_template.format('function', magic_kind)
254
254
255 ds += dedent("""
255 ds += dedent("""
256 Note: this decorator can only be used in a context where IPython is already
256 Note: this decorator can only be used in a context where IPython is already
257 active, so that the `get_ipython()` call succeeds. You can therefore use
257 active, so that the `get_ipython()` call succeeds. You can therefore use
258 it in your startup files loaded after IPython initializes, but *not* in the
258 it in your startup files loaded after IPython initializes, but *not* in the
259 IPython configuration file itself, which is executed before IPython is
259 IPython configuration file itself, which is executed before IPython is
260 fully up and running. Any file located in the `startup` subdirectory of
260 fully up and running. Any file located in the `startup` subdirectory of
261 your configuration profile will be OK in this sense.
261 your configuration profile will be OK in this sense.
262 """)
262 """)
263
263
264 magic_deco.__doc__ = ds
264 magic_deco.__doc__ = ds
265 return magic_deco
265 return magic_deco
266
266
267
267
268 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
268 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
269
269
270
270
271 def no_var_expand(magic_func):
271 def no_var_expand(magic_func):
272 """Mark a magic function as not needing variable expansion
272 """Mark a magic function as not needing variable expansion
273
273
274 By default, IPython interprets `{a}` or `$a` in the line passed to magics
274 By default, IPython interprets `{a}` or `$a` in the line passed to magics
275 as variables that should be interpolated from the interactive namespace
275 as variables that should be interpolated from the interactive namespace
276 before passing the line to the magic function.
276 before passing the line to the magic function.
277 This is not always desirable, e.g. when the magic executes Python code
277 This is not always desirable, e.g. when the magic executes Python code
278 (%timeit, %time, etc.).
278 (%timeit, %time, etc.).
279 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
279 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
280
280
281 .. versionadded:: 7.3
281 .. versionadded:: 7.3
282 """
282 """
283 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
283 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
284 return magic_func
284 return magic_func
285
285
286
286
287 # Create the actual decorators for public use
287 # Create the actual decorators for public use
288
288
289 # These three are used to decorate methods in class definitions
289 # These three are used to decorate methods in class definitions
290 line_magic = _method_magic_marker('line')
290 line_magic = _method_magic_marker('line')
291 cell_magic = _method_magic_marker('cell')
291 cell_magic = _method_magic_marker('cell')
292 line_cell_magic = _method_magic_marker('line_cell')
292 line_cell_magic = _method_magic_marker('line_cell')
293
293
294 # These three decorate standalone functions and perform the decoration
294 # These three decorate standalone functions and perform the decoration
295 # immediately. They can only run where get_ipython() works
295 # immediately. They can only run where get_ipython() works
296 register_line_magic = _function_magic_marker('line')
296 register_line_magic = _function_magic_marker('line')
297 register_cell_magic = _function_magic_marker('cell')
297 register_cell_magic = _function_magic_marker('cell')
298 register_line_cell_magic = _function_magic_marker('line_cell')
298 register_line_cell_magic = _function_magic_marker('line_cell')
299
299
300 #-----------------------------------------------------------------------------
300 #-----------------------------------------------------------------------------
301 # Core Magic classes
301 # Core Magic classes
302 #-----------------------------------------------------------------------------
302 #-----------------------------------------------------------------------------
303
303
304 class MagicsManager(Configurable):
304 class MagicsManager(Configurable):
305 """Object that handles all magic-related functionality for IPython.
305 """Object that handles all magic-related functionality for IPython.
306 """
306 """
307 # Non-configurable class attributes
307 # Non-configurable class attributes
308
308
309 # A two-level dict, first keyed by magic type, then by magic function, and
309 # A two-level dict, first keyed by magic type, then by magic function, and
310 # holding the actual callable object as value. This is the dict used for
310 # holding the actual callable object as value. This is the dict used for
311 # magic function dispatch
311 # magic function dispatch
312 magics = Dict()
312 magics = Dict()
313
313
314 # A registry of the original objects that we've been given holding magics.
314 # A registry of the original objects that we've been given holding magics.
315 registry = Dict()
315 registry = Dict()
316
316
317 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
317 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
318
318
319 auto_magic = Bool(True, help=
319 auto_magic = Bool(True, help=
320 "Automatically call line magics without requiring explicit % prefix"
320 "Automatically call line magics without requiring explicit % prefix"
321 ).tag(config=True)
321 ).tag(config=True)
322 @observe('auto_magic')
322 @observe('auto_magic')
323 def _auto_magic_changed(self, change):
323 def _auto_magic_changed(self, change):
324 self.shell.automagic = change['new']
324 self.shell.automagic = change['new']
325
325
326 _auto_status = [
326 _auto_status = [
327 'Automagic is OFF, % prefix IS needed for line magics.',
327 'Automagic is OFF, % prefix IS needed for line magics.',
328 'Automagic is ON, % prefix IS NOT needed for line magics.']
328 'Automagic is ON, % prefix IS NOT needed for line magics.']
329
329
330 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
330 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
331
331
332 def __init__(self, shell=None, config=None, user_magics=None, **traits):
332 def __init__(self, shell=None, config=None, user_magics=None, **traits):
333
333
334 super(MagicsManager, self).__init__(shell=shell, config=config,
334 super(MagicsManager, self).__init__(shell=shell, config=config,
335 user_magics=user_magics, **traits)
335 user_magics=user_magics, **traits)
336 self.magics = dict(line={}, cell={})
336 self.magics = dict(line={}, cell={})
337 # Let's add the user_magics to the registry for uniformity, so *all*
337 # Let's add the user_magics to the registry for uniformity, so *all*
338 # registered magic containers can be found there.
338 # registered magic containers can be found there.
339 self.registry[user_magics.__class__.__name__] = user_magics
339 self.registry[user_magics.__class__.__name__] = user_magics
340
340
341 def auto_status(self):
341 def auto_status(self):
342 """Return descriptive string with automagic status."""
342 """Return descriptive string with automagic status."""
343 return self._auto_status[self.auto_magic]
343 return self._auto_status[self.auto_magic]
344
344
345 def lsmagic(self):
345 def lsmagic(self):
346 """Return a dict of currently available magic functions.
346 """Return a dict of currently available magic functions.
347
347
348 The return dict has the keys 'line' and 'cell', corresponding to the
348 The return dict has the keys 'line' and 'cell', corresponding to the
349 two types of magics we support. Each value is a list of names.
349 two types of magics we support. Each value is a list of names.
350 """
350 """
351 return self.magics
351 return self.magics
352
352
353 def lsmagic_docs(self, brief=False, missing=''):
353 def lsmagic_docs(self, brief=False, missing=''):
354 """Return dict of documentation of magic functions.
354 """Return dict of documentation of magic functions.
355
355
356 The return dict has the keys 'line' and 'cell', corresponding to the
356 The return dict has the keys 'line' and 'cell', corresponding to the
357 two types of magics we support. Each value is a dict keyed by magic
357 two types of magics we support. Each value is a dict keyed by magic
358 name whose value is the function docstring. If a docstring is
358 name whose value is the function docstring. If a docstring is
359 unavailable, the value of `missing` is used instead.
359 unavailable, the value of `missing` is used instead.
360
360
361 If brief is True, only the first line of each docstring will be returned.
361 If brief is True, only the first line of each docstring will be returned.
362 """
362 """
363 docs = {}
363 docs = {}
364 for m_type in self.magics:
364 for m_type in self.magics:
365 m_docs = {}
365 m_docs = {}
366 for m_name, m_func in self.magics[m_type].items():
366 for m_name, m_func in self.magics[m_type].items():
367 if m_func.__doc__:
367 if m_func.__doc__:
368 if brief:
368 if brief:
369 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
369 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
370 else:
370 else:
371 m_docs[m_name] = m_func.__doc__.rstrip()
371 m_docs[m_name] = m_func.__doc__.rstrip()
372 else:
372 else:
373 m_docs[m_name] = missing
373 m_docs[m_name] = missing
374 docs[m_type] = m_docs
374 docs[m_type] = m_docs
375 return docs
375 return docs
376
376
377 def register(self, *magic_objects):
377 def register(self, *magic_objects):
378 """Register one or more instances of Magics.
378 """Register one or more instances of Magics.
379
379
380 Take one or more classes or instances of classes that subclass the main
380 Take one or more classes or instances of classes that subclass the main
381 `core.Magic` class, and register them with IPython to use the magic
381 `core.Magic` class, and register them with IPython to use the magic
382 functions they provide. The registration process will then ensure that
382 functions they provide. The registration process will then ensure that
383 any methods that have decorated to provide line and/or cell magics will
383 any methods that have decorated to provide line and/or cell magics will
384 be recognized with the `%x`/`%%x` syntax as a line/cell magic
384 be recognized with the `%x`/`%%x` syntax as a line/cell magic
385 respectively.
385 respectively.
386
386
387 If classes are given, they will be instantiated with the default
387 If classes are given, they will be instantiated with the default
388 constructor. If your classes need a custom constructor, you should
388 constructor. If your classes need a custom constructor, you should
389 instanitate them first and pass the instance.
389 instanitate them first and pass the instance.
390
390
391 The provided arguments can be an arbitrary mix of classes and instances.
391 The provided arguments can be an arbitrary mix of classes and instances.
392
392
393 Parameters
393 Parameters
394 ----------
394 ----------
395 magic_objects : one or more classes or instances
395 magic_objects : one or more classes or instances
396 """
396 """
397 # Start by validating them to ensure they have all had their magic
397 # Start by validating them to ensure they have all had their magic
398 # methods registered at the instance level
398 # methods registered at the instance level
399 for m in magic_objects:
399 for m in magic_objects:
400 if not m.registered:
400 if not m.registered:
401 raise ValueError("Class of magics %r was constructed without "
401 raise ValueError("Class of magics %r was constructed without "
402 "the @register_magics class decorator")
402 "the @register_magics class decorator")
403 if isinstance(m, type):
403 if isinstance(m, type):
404 # If we're given an uninstantiated class
404 # If we're given an uninstantiated class
405 m = m(shell=self.shell)
405 m = m(shell=self.shell)
406
406
407 # Now that we have an instance, we can register it and update the
407 # Now that we have an instance, we can register it and update the
408 # table of callables
408 # table of callables
409 self.registry[m.__class__.__name__] = m
409 self.registry[m.__class__.__name__] = m
410 for mtype in magic_kinds:
410 for mtype in magic_kinds:
411 self.magics[mtype].update(m.magics[mtype])
411 self.magics[mtype].update(m.magics[mtype])
412
412
413 def register_function(self, func, magic_kind='line', magic_name=None):
413 def register_function(self, func, magic_kind='line', magic_name=None):
414 """Expose a standalone function as magic function for IPython.
414 """Expose a standalone function as magic function for IPython.
415
415
416 This will create an IPython magic (line, cell or both) from a
416 This will create an IPython magic (line, cell or both) from a
417 standalone function. The functions should have the following
417 standalone function. The functions should have the following
418 signatures:
418 signatures:
419
419
420 * For line magics: `def f(line)`
420 * For line magics: `def f(line)`
421 * For cell magics: `def f(line, cell)`
421 * For cell magics: `def f(line, cell)`
422 * For a function that does both: `def f(line, cell=None)`
422 * For a function that does both: `def f(line, cell=None)`
423
423
424 In the latter case, the function will be called with `cell==None` when
424 In the latter case, the function will be called with `cell==None` when
425 invoked as `%f`, and with cell as a string when invoked as `%%f`.
425 invoked as `%f`, and with cell as a string when invoked as `%%f`.
426
426
427 Parameters
427 Parameters
428 ----------
428 ----------
429 func : callable
429 func : callable
430 Function to be registered as a magic.
430 Function to be registered as a magic.
431
431
432 magic_kind : str
432 magic_kind : str
433 Kind of magic, one of 'line', 'cell' or 'line_cell'
433 Kind of magic, one of 'line', 'cell' or 'line_cell'
434
434
435 magic_name : optional str
435 magic_name : optional str
436 If given, the name the magic will have in the IPython namespace. By
436 If given, the name the magic will have in the IPython namespace. By
437 default, the name of the function itself is used.
437 default, the name of the function itself is used.
438 """
438 """
439
439
440 # Create the new method in the user_magics and register it in the
440 # Create the new method in the user_magics and register it in the
441 # global table
441 # global table
442 validate_type(magic_kind)
442 validate_type(magic_kind)
443 magic_name = func.__name__ if magic_name is None else magic_name
443 magic_name = func.__name__ if magic_name is None else magic_name
444 setattr(self.user_magics, magic_name, func)
444 setattr(self.user_magics, magic_name, func)
445 record_magic(self.magics, magic_kind, magic_name, func)
445 record_magic(self.magics, magic_kind, magic_name, func)
446
446
447 def register_alias(self, alias_name, magic_name, magic_kind='line', magic_params=None):
447 def register_alias(self, alias_name, magic_name, magic_kind='line', magic_params=None):
448 """Register an alias to a magic function.
448 """Register an alias to a magic function.
449
449
450 The alias is an instance of :class:`MagicAlias`, which holds the
450 The alias is an instance of :class:`MagicAlias`, which holds the
451 name and kind of the magic it should call. Binding is done at
451 name and kind of the magic it should call. Binding is done at
452 call time, so if the underlying magic function is changed the alias
452 call time, so if the underlying magic function is changed the alias
453 will call the new function.
453 will call the new function.
454
454
455 Parameters
455 Parameters
456 ----------
456 ----------
457 alias_name : str
457 alias_name : str
458 The name of the magic to be registered.
458 The name of the magic to be registered.
459
459
460 magic_name : str
460 magic_name : str
461 The name of an existing magic.
461 The name of an existing magic.
462
462
463 magic_kind : str
463 magic_kind : str
464 Kind of magic, one of 'line' or 'cell'
464 Kind of magic, one of 'line' or 'cell'
465 """
465 """
466
466
467 # `validate_type` is too permissive, as it allows 'line_cell'
467 # `validate_type` is too permissive, as it allows 'line_cell'
468 # which we do not handle.
468 # which we do not handle.
469 if magic_kind not in magic_kinds:
469 if magic_kind not in magic_kinds:
470 raise ValueError('magic_kind must be one of %s, %s given' %
470 raise ValueError('magic_kind must be one of %s, %s given' %
471 magic_kinds, magic_kind)
471 magic_kinds, magic_kind)
472
472
473 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params)
473 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params)
474 setattr(self.user_magics, alias_name, alias)
474 setattr(self.user_magics, alias_name, alias)
475 record_magic(self.magics, magic_kind, alias_name, alias)
475 record_magic(self.magics, magic_kind, alias_name, alias)
476
476
477 # Key base class that provides the central functionality for magics.
477 # Key base class that provides the central functionality for magics.
478
478
479
479
480 class Magics(Configurable):
480 class Magics(Configurable):
481 """Base class for implementing magic functions.
481 """Base class for implementing magic functions.
482
482
483 Shell functions which can be reached as %function_name. All magic
483 Shell functions which can be reached as %function_name. All magic
484 functions should accept a string, which they can parse for their own
484 functions should accept a string, which they can parse for their own
485 needs. This can make some functions easier to type, eg `%cd ../`
485 needs. This can make some functions easier to type, eg `%cd ../`
486 vs. `%cd("../")`
486 vs. `%cd("../")`
487
487
488 Classes providing magic functions need to subclass this class, and they
488 Classes providing magic functions need to subclass this class, and they
489 MUST:
489 MUST:
490
490
491 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
491 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
492 individual methods as magic functions, AND
492 individual methods as magic functions, AND
493
493
494 - Use the class decorator `@magics_class` to ensure that the magic
494 - Use the class decorator `@magics_class` to ensure that the magic
495 methods are properly registered at the instance level upon instance
495 methods are properly registered at the instance level upon instance
496 initialization.
496 initialization.
497
497
498 See :mod:`magic_functions` for examples of actual implementation classes.
498 See :mod:`magic_functions` for examples of actual implementation classes.
499 """
499 """
500 # Dict holding all command-line options for each magic.
500 # Dict holding all command-line options for each magic.
501 options_table = None
501 options_table = None
502 # Dict for the mapping of magic names to methods, set by class decorator
502 # Dict for the mapping of magic names to methods, set by class decorator
503 magics = None
503 magics = None
504 # Flag to check that the class decorator was properly applied
504 # Flag to check that the class decorator was properly applied
505 registered = False
505 registered = False
506 # Instance of IPython shell
506 # Instance of IPython shell
507 shell = None
507 shell = None
508
508
509 def __init__(self, shell=None, **kwargs):
509 def __init__(self, shell=None, **kwargs):
510 if not(self.__class__.registered):
510 if not(self.__class__.registered):
511 raise ValueError('Magics subclass without registration - '
511 raise ValueError('Magics subclass without registration - '
512 'did you forget to apply @magics_class?')
512 'did you forget to apply @magics_class?')
513 if shell is not None:
513 if shell is not None:
514 if hasattr(shell, 'configurables'):
514 if hasattr(shell, 'configurables'):
515 shell.configurables.append(self)
515 shell.configurables.append(self)
516 if hasattr(shell, 'config'):
516 if hasattr(shell, 'config'):
517 kwargs.setdefault('parent', shell)
517 kwargs.setdefault('parent', shell)
518
518
519 self.shell = shell
519 self.shell = shell
520 self.options_table = {}
520 self.options_table = {}
521 # The method decorators are run when the instance doesn't exist yet, so
521 # The method decorators are run when the instance doesn't exist yet, so
522 # they can only record the names of the methods they are supposed to
522 # they can only record the names of the methods they are supposed to
523 # grab. Only now, that the instance exists, can we create the proper
523 # grab. Only now, that the instance exists, can we create the proper
524 # mapping to bound methods. So we read the info off the original names
524 # mapping to bound methods. So we read the info off the original names
525 # table and replace each method name by the actual bound method.
525 # table and replace each method name by the actual bound method.
526 # But we mustn't clobber the *class* mapping, in case of multiple instances.
526 # But we mustn't clobber the *class* mapping, in case of multiple instances.
527 class_magics = self.magics
527 class_magics = self.magics
528 self.magics = {}
528 self.magics = {}
529 for mtype in magic_kinds:
529 for mtype in magic_kinds:
530 tab = self.magics[mtype] = {}
530 tab = self.magics[mtype] = {}
531 cls_tab = class_magics[mtype]
531 cls_tab = class_magics[mtype]
532 for magic_name, meth_name in cls_tab.items():
532 for magic_name, meth_name in cls_tab.items():
533 if isinstance(meth_name, str):
533 if isinstance(meth_name, str):
534 # it's a method name, grab it
534 # it's a method name, grab it
535 tab[magic_name] = getattr(self, meth_name)
535 tab[magic_name] = getattr(self, meth_name)
536 else:
536 else:
537 # it's the real thing
537 # it's the real thing
538 tab[magic_name] = meth_name
538 tab[magic_name] = meth_name
539 # Configurable **needs** to be initiated at the end or the config
539 # Configurable **needs** to be initiated at the end or the config
540 # magics get screwed up.
540 # magics get screwed up.
541 super(Magics, self).__init__(**kwargs)
541 super(Magics, self).__init__(**kwargs)
542
542
543 def arg_err(self,func):
543 def arg_err(self,func):
544 """Print docstring if incorrect arguments were passed"""
544 """Print docstring if incorrect arguments were passed"""
545 print('Error in arguments:')
545 print('Error in arguments:')
546 print(oinspect.getdoc(func))
546 print(oinspect.getdoc(func))
547
547
548 def format_latex(self, strng):
548 def format_latex(self, strng):
549 """Format a string for latex inclusion."""
549 """Format a string for latex inclusion."""
550
550
551 # Characters that need to be escaped for latex:
551 # Characters that need to be escaped for latex:
552 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
552 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
553 # Magic command names as headers:
553 # Magic command names as headers:
554 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
554 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
555 re.MULTILINE)
555 re.MULTILINE)
556 # Magic commands
556 # Magic commands
557 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
557 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
558 re.MULTILINE)
558 re.MULTILINE)
559 # Paragraph continue
559 # Paragraph continue
560 par_re = re.compile(r'\\$',re.MULTILINE)
560 par_re = re.compile(r'\\$',re.MULTILINE)
561
561
562 # The "\n" symbol
562 # The "\n" symbol
563 newline_re = re.compile(r'\\n')
563 newline_re = re.compile(r'\\n')
564
564
565 # Now build the string for output:
565 # Now build the string for output:
566 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
566 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
567 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
567 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
568 strng)
568 strng)
569 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
569 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
570 strng = par_re.sub(r'\\\\',strng)
570 strng = par_re.sub(r'\\\\',strng)
571 strng = escape_re.sub(r'\\\1',strng)
571 strng = escape_re.sub(r'\\\1',strng)
572 strng = newline_re.sub(r'\\textbackslash{}n',strng)
572 strng = newline_re.sub(r'\\textbackslash{}n',strng)
573 return strng
573 return strng
574
574
575 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
575 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
576 """Parse options passed to an argument string.
576 """Parse options passed to an argument string.
577
577
578 The interface is similar to that of :func:`getopt.getopt`, but it
578 The interface is similar to that of :func:`getopt.getopt`, but it
579 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
579 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
580 and the stripped argument string still as a string.
580 and the stripped argument string still as a string.
581
581
582 arg_str is quoted as a true sys.argv vector by using shlex.split.
582 arg_str is quoted as a true sys.argv vector by using shlex.split.
583 This allows us to easily expand variables, glob files, quote
583 This allows us to easily expand variables, glob files, quote
584 arguments, etc.
584 arguments, etc.
585
585
586 Parameters
586 Parameters
587 ----------
587 ----------
588
588
589 arg_str : str
589 arg_str : str
590 The arguments to parse.
590 The arguments to parse.
591
591
592 opt_str : str
592 opt_str : str
593 The options specification.
593 The options specification.
594
594
595 mode : str, default 'string'
595 mode : str, default 'string'
596 If given as 'list', the argument string is returned as a list (split
596 If given as 'list', the argument string is returned as a list (split
597 on whitespace) instead of a string.
597 on whitespace) instead of a string.
598
598
599 list_all : bool, default False
599 list_all : bool, default False
600 Put all option values in lists. Normally only options
600 Put all option values in lists. Normally only options
601 appearing more than once are put in a list.
601 appearing more than once are put in a list.
602
602
603 posix : bool, default True
603 posix : bool, default True
604 Whether to split the input line in POSIX mode or not, as per the
604 Whether to split the input line in POSIX mode or not, as per the
605 conventions outlined in the :mod:`shlex` module from the standard
605 conventions outlined in the :mod:`shlex` module from the standard
606 library.
606 library.
607 """
607 """
608
608
609 # inject default options at the beginning of the input line
609 # inject default options at the beginning of the input line
610 caller = sys._getframe(1).f_code.co_name
610 caller = sys._getframe(1).f_code.co_name
611 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
611 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
612
612
613 mode = kw.get('mode','string')
613 mode = kw.get('mode','string')
614 if mode not in ['string','list']:
614 if mode not in ['string','list']:
615 raise ValueError('incorrect mode given: %s' % mode)
615 raise ValueError('incorrect mode given: %s' % mode)
616 # Get options
616 # Get options
617 list_all = kw.get('list_all',0)
617 list_all = kw.get('list_all',0)
618 posix = kw.get('posix', os.name == 'posix')
618 posix = kw.get('posix', os.name == 'posix')
619 strict = kw.get('strict', True)
619 strict = kw.get('strict', True)
620
620
621 preserve_non_opts = kw.get('preserve_non_opts', False)
621 preserve_non_opts = kw.get("preserve_non_opts", False)
622 remainder_arg_str = arg_str
622 remainder_arg_str = arg_str
623
623
624 # Check if we have more than one argument to warrant extra processing:
624 # Check if we have more than one argument to warrant extra processing:
625 odict = {} # Dictionary with options
625 odict = {} # Dictionary with options
626 args = arg_str.split()
626 args = arg_str.split()
627 if len(args) >= 1:
627 if len(args) >= 1:
628 # If the list of inputs only has 0 or 1 thing in it, there's no
628 # If the list of inputs only has 0 or 1 thing in it, there's no
629 # need to look for options
629 # need to look for options
630 argv = arg_split(arg_str, posix, strict)
630 argv = arg_split(arg_str, posix, strict)
631 # Do regular option processing
631 # Do regular option processing
632 try:
632 try:
633 opts,args = getopt(argv, opt_str, long_opts)
633 opts,args = getopt(argv, opt_str, long_opts)
634 except GetoptError as e:
634 except GetoptError as e:
635 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
635 raise UsageError(
636 " ".join(long_opts))) from e
636 '%s ( allowed: "%s" %s)' % (e.msg, opt_str, " ".join(long_opts))
637 for o,a in opts:
637 ) from e
638 if mode is 'string' and preserve_non_opts:
638 for o, a in opts:
639 if mode is "string" and preserve_non_opts:
639 # remove option-parts from the original args-string and preserve remaining-part.
640 # remove option-parts from the original args-string and preserve remaining-part.
640 # This relies on the arg_split(...) and getopt(...)'s impl spec, that the parsed options are
641 # This relies on the arg_split(...) and getopt(...)'s impl spec, that the parsed options are
641 # returned in the original order.
642 # returned in the original order.
642 remainder_arg_str = remainder_arg_str.replace(o, '', 1).replace(a, '', 1)
643 remainder_arg_str = remainder_arg_str.replace(o, "", 1).replace(
643 if o.startswith('--'):
644 a, "", 1
645 )
646 if o.startswith("--"):
644 o = o[2:]
647 o = o[2:]
645 else:
648 else:
646 o = o[1:]
649 o = o[1:]
647 try:
650 try:
648 odict[o].append(a)
651 odict[o].append(a)
649 except AttributeError:
652 except AttributeError:
650 odict[o] = [odict[o],a]
653 odict[o] = [odict[o],a]
651 except KeyError:
654 except KeyError:
652 if list_all:
655 if list_all:
653 odict[o] = [a]
656 odict[o] = [a]
654 else:
657 else:
655 odict[o] = a
658 odict[o] = a
656
659
657 # Prepare opts,args for return
660 # Prepare opts,args for return
658 opts = Struct(odict)
661 opts = Struct(odict)
659 if mode == 'string':
662 if mode == 'string':
660 if preserve_non_opts:
663 if preserve_non_opts:
661 args = remainder_arg_str.lstrip()
664 args = remainder_arg_str.lstrip()
662 else:
665 else:
663 args = ' '.join(args)
666 args = ' '.join(args)
664
667
665 return opts,args
668 return opts,args
666
669
667 def default_option(self, fn, optstr):
670 def default_option(self, fn, optstr):
668 """Make an entry in the options_table for fn, with value optstr"""
671 """Make an entry in the options_table for fn, with value optstr"""
669
672
670 if fn not in self.lsmagic():
673 if fn not in self.lsmagic():
671 error("%s is not a magic function" % fn)
674 error("%s is not a magic function" % fn)
672 self.options_table[fn] = optstr
675 self.options_table[fn] = optstr
673
676
674
677
675 class MagicAlias(object):
678 class MagicAlias(object):
676 """An alias to another magic function.
679 """An alias to another magic function.
677
680
678 An alias is determined by its magic name and magic kind. Lookup
681 An alias is determined by its magic name and magic kind. Lookup
679 is done at call time, so if the underlying magic changes the alias
682 is done at call time, so if the underlying magic changes the alias
680 will call the new function.
683 will call the new function.
681
684
682 Use the :meth:`MagicsManager.register_alias` method or the
685 Use the :meth:`MagicsManager.register_alias` method or the
683 `%alias_magic` magic function to create and register a new alias.
686 `%alias_magic` magic function to create and register a new alias.
684 """
687 """
685 def __init__(self, shell, magic_name, magic_kind, magic_params=None):
688 def __init__(self, shell, magic_name, magic_kind, magic_params=None):
686 self.shell = shell
689 self.shell = shell
687 self.magic_name = magic_name
690 self.magic_name = magic_name
688 self.magic_params = magic_params
691 self.magic_params = magic_params
689 self.magic_kind = magic_kind
692 self.magic_kind = magic_kind
690
693
691 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
694 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
692 self.__doc__ = "Alias for `%s`." % self.pretty_target
695 self.__doc__ = "Alias for `%s`." % self.pretty_target
693
696
694 self._in_call = False
697 self._in_call = False
695
698
696 def __call__(self, *args, **kwargs):
699 def __call__(self, *args, **kwargs):
697 """Call the magic alias."""
700 """Call the magic alias."""
698 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
701 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
699 if fn is None:
702 if fn is None:
700 raise UsageError("Magic `%s` not found." % self.pretty_target)
703 raise UsageError("Magic `%s` not found." % self.pretty_target)
701
704
702 # Protect against infinite recursion.
705 # Protect against infinite recursion.
703 if self._in_call:
706 if self._in_call:
704 raise UsageError("Infinite recursion detected; "
707 raise UsageError("Infinite recursion detected; "
705 "magic aliases cannot call themselves.")
708 "magic aliases cannot call themselves.")
706 self._in_call = True
709 self._in_call = True
707 try:
710 try:
708 if self.magic_params:
711 if self.magic_params:
709 args_list = list(args)
712 args_list = list(args)
710 args_list[0] = self.magic_params + " " + args[0]
713 args_list[0] = self.magic_params + " " + args[0]
711 args = tuple(args_list)
714 args = tuple(args_list)
712 return fn(*args, **kwargs)
715 return fn(*args, **kwargs)
713 finally:
716 finally:
714 self._in_call = False
717 self._in_call = False
@@ -1,1502 +1,1503 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions."""
2 """Implementation of execution-related magic functions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import ast
8 import ast
9 import bdb
9 import bdb
10 import builtins as builtin_mod
10 import builtins as builtin_mod
11 import gc
11 import gc
12 import itertools
12 import itertools
13 import os
13 import os
14 import shlex
14 import shlex
15 import sys
15 import sys
16 import time
16 import time
17 import timeit
17 import timeit
18 import math
18 import math
19 import re
19 import re
20 from pdb import Restart
20 from pdb import Restart
21
21
22 import cProfile as profile
22 import cProfile as profile
23 import pstats
23 import pstats
24
24
25 from IPython.core import oinspect
25 from IPython.core import oinspect
26 from IPython.core import magic_arguments
26 from IPython.core import magic_arguments
27 from IPython.core import page
27 from IPython.core import page
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29 from IPython.core.macro import Macro
29 from IPython.core.macro import Macro
30 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
30 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
31 line_cell_magic, on_off, needs_local_scope,
31 line_cell_magic, on_off, needs_local_scope,
32 no_var_expand)
32 no_var_expand)
33 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.contexts import preserve_keys
34 from IPython.utils.contexts import preserve_keys
35 from IPython.utils.capture import capture_output
35 from IPython.utils.capture import capture_output
36 from IPython.utils.ipstruct import Struct
36 from IPython.utils.ipstruct import Struct
37 from IPython.utils.module_paths import find_mod
37 from IPython.utils.module_paths import find_mod
38 from IPython.utils.path import get_py_filename, shellglob
38 from IPython.utils.path import get_py_filename, shellglob
39 from IPython.utils.timing import clock, clock2
39 from IPython.utils.timing import clock, clock2
40 from warnings import warn
40 from warnings import warn
41 from logging import error
41 from logging import error
42 from pathlib import Path
42 from pathlib import Path
43 from io import StringIO
43 from io import StringIO
44 from pathlib import Path
44 from pathlib import Path
45
45
46 if sys.version_info > (3,8):
46 if sys.version_info > (3,8):
47 from ast import Module
47 from ast import Module
48 else :
48 else :
49 # mock the new API, ignore second argument
49 # mock the new API, ignore second argument
50 # see https://github.com/ipython/ipython/issues/11590
50 # see https://github.com/ipython/ipython/issues/11590
51 from ast import Module as OriginalModule
51 from ast import Module as OriginalModule
52 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
52 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
53
53
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Magic implementation classes
56 # Magic implementation classes
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59
59
60 class TimeitResult(object):
60 class TimeitResult(object):
61 """
61 """
62 Object returned by the timeit magic with info about the run.
62 Object returned by the timeit magic with info about the run.
63
63
64 Contains the following attributes :
64 Contains the following attributes :
65
65
66 loops: (int) number of loops done per measurement
66 loops: (int) number of loops done per measurement
67 repeat: (int) number of times the measurement has been repeated
67 repeat: (int) number of times the measurement has been repeated
68 best: (float) best execution time / number
68 best: (float) best execution time / number
69 all_runs: (list of float) execution time of each run (in s)
69 all_runs: (list of float) execution time of each run (in s)
70 compile_time: (float) time of statement compilation (s)
70 compile_time: (float) time of statement compilation (s)
71
71
72 """
72 """
73 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
74 self.loops = loops
74 self.loops = loops
75 self.repeat = repeat
75 self.repeat = repeat
76 self.best = best
76 self.best = best
77 self.worst = worst
77 self.worst = worst
78 self.all_runs = all_runs
78 self.all_runs = all_runs
79 self.compile_time = compile_time
79 self.compile_time = compile_time
80 self._precision = precision
80 self._precision = precision
81 self.timings = [ dt / self.loops for dt in all_runs]
81 self.timings = [ dt / self.loops for dt in all_runs]
82
82
83 @property
83 @property
84 def average(self):
84 def average(self):
85 return math.fsum(self.timings) / len(self.timings)
85 return math.fsum(self.timings) / len(self.timings)
86
86
87 @property
87 @property
88 def stdev(self):
88 def stdev(self):
89 mean = self.average
89 mean = self.average
90 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
90 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
91
91
92 def __str__(self):
92 def __str__(self):
93 pm = '+-'
93 pm = '+-'
94 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
94 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
95 try:
95 try:
96 u'\xb1'.encode(sys.stdout.encoding)
96 u'\xb1'.encode(sys.stdout.encoding)
97 pm = u'\xb1'
97 pm = u'\xb1'
98 except:
98 except:
99 pass
99 pass
100 return (
100 return (
101 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
101 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
102 .format(
102 .format(
103 pm = pm,
103 pm = pm,
104 runs = self.repeat,
104 runs = self.repeat,
105 loops = self.loops,
105 loops = self.loops,
106 loop_plural = "" if self.loops == 1 else "s",
106 loop_plural = "" if self.loops == 1 else "s",
107 run_plural = "" if self.repeat == 1 else "s",
107 run_plural = "" if self.repeat == 1 else "s",
108 mean = _format_time(self.average, self._precision),
108 mean = _format_time(self.average, self._precision),
109 std = _format_time(self.stdev, self._precision))
109 std = _format_time(self.stdev, self._precision))
110 )
110 )
111
111
112 def _repr_pretty_(self, p , cycle):
112 def _repr_pretty_(self, p , cycle):
113 unic = self.__str__()
113 unic = self.__str__()
114 p.text(u'<TimeitResult : '+unic+u'>')
114 p.text(u'<TimeitResult : '+unic+u'>')
115
115
116
116
117 class TimeitTemplateFiller(ast.NodeTransformer):
117 class TimeitTemplateFiller(ast.NodeTransformer):
118 """Fill in the AST template for timing execution.
118 """Fill in the AST template for timing execution.
119
119
120 This is quite closely tied to the template definition, which is in
120 This is quite closely tied to the template definition, which is in
121 :meth:`ExecutionMagics.timeit`.
121 :meth:`ExecutionMagics.timeit`.
122 """
122 """
123 def __init__(self, ast_setup, ast_stmt):
123 def __init__(self, ast_setup, ast_stmt):
124 self.ast_setup = ast_setup
124 self.ast_setup = ast_setup
125 self.ast_stmt = ast_stmt
125 self.ast_stmt = ast_stmt
126
126
127 def visit_FunctionDef(self, node):
127 def visit_FunctionDef(self, node):
128 "Fill in the setup statement"
128 "Fill in the setup statement"
129 self.generic_visit(node)
129 self.generic_visit(node)
130 if node.name == "inner":
130 if node.name == "inner":
131 node.body[:1] = self.ast_setup.body
131 node.body[:1] = self.ast_setup.body
132
132
133 return node
133 return node
134
134
135 def visit_For(self, node):
135 def visit_For(self, node):
136 "Fill in the statement to be timed"
136 "Fill in the statement to be timed"
137 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
137 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
138 node.body = self.ast_stmt.body
138 node.body = self.ast_stmt.body
139 return node
139 return node
140
140
141
141
142 class Timer(timeit.Timer):
142 class Timer(timeit.Timer):
143 """Timer class that explicitly uses self.inner
143 """Timer class that explicitly uses self.inner
144
144
145 which is an undocumented implementation detail of CPython,
145 which is an undocumented implementation detail of CPython,
146 not shared by PyPy.
146 not shared by PyPy.
147 """
147 """
148 # Timer.timeit copied from CPython 3.4.2
148 # Timer.timeit copied from CPython 3.4.2
149 def timeit(self, number=timeit.default_number):
149 def timeit(self, number=timeit.default_number):
150 """Time 'number' executions of the main statement.
150 """Time 'number' executions of the main statement.
151
151
152 To be precise, this executes the setup statement once, and
152 To be precise, this executes the setup statement once, and
153 then returns the time it takes to execute the main statement
153 then returns the time it takes to execute the main statement
154 a number of times, as a float measured in seconds. The
154 a number of times, as a float measured in seconds. The
155 argument is the number of times through the loop, defaulting
155 argument is the number of times through the loop, defaulting
156 to one million. The main statement, the setup statement and
156 to one million. The main statement, the setup statement and
157 the timer function to be used are passed to the constructor.
157 the timer function to be used are passed to the constructor.
158 """
158 """
159 it = itertools.repeat(None, number)
159 it = itertools.repeat(None, number)
160 gcold = gc.isenabled()
160 gcold = gc.isenabled()
161 gc.disable()
161 gc.disable()
162 try:
162 try:
163 timing = self.inner(it, self.timer)
163 timing = self.inner(it, self.timer)
164 finally:
164 finally:
165 if gcold:
165 if gcold:
166 gc.enable()
166 gc.enable()
167 return timing
167 return timing
168
168
169
169
170 @magics_class
170 @magics_class
171 class ExecutionMagics(Magics):
171 class ExecutionMagics(Magics):
172 """Magics related to code execution, debugging, profiling, etc.
172 """Magics related to code execution, debugging, profiling, etc.
173
173
174 """
174 """
175
175
176 def __init__(self, shell):
176 def __init__(self, shell):
177 super(ExecutionMagics, self).__init__(shell)
177 super(ExecutionMagics, self).__init__(shell)
178 # Default execution function used to actually run user code.
178 # Default execution function used to actually run user code.
179 self.default_runner = None
179 self.default_runner = None
180
180
181 @skip_doctest
181 @skip_doctest
182 @no_var_expand
182 @no_var_expand
183 @line_cell_magic
183 @line_cell_magic
184 def prun(self, parameter_s='', cell=None):
184 def prun(self, parameter_s='', cell=None):
185
185
186 """Run a statement through the python code profiler.
186 """Run a statement through the python code profiler.
187
187
188 Usage, in line mode:
188 Usage, in line mode:
189 %prun [options] statement
189 %prun [options] statement
190
190
191 Usage, in cell mode:
191 Usage, in cell mode:
192 %%prun [options] [statement]
192 %%prun [options] [statement]
193 code...
193 code...
194 code...
194 code...
195
195
196 In cell mode, the additional code lines are appended to the (possibly
196 In cell mode, the additional code lines are appended to the (possibly
197 empty) statement in the first line. Cell mode allows you to easily
197 empty) statement in the first line. Cell mode allows you to easily
198 profile multiline blocks without having to put them in a separate
198 profile multiline blocks without having to put them in a separate
199 function.
199 function.
200
200
201 The given statement (which doesn't require quote marks) is run via the
201 The given statement (which doesn't require quote marks) is run via the
202 python profiler in a manner similar to the profile.run() function.
202 python profiler in a manner similar to the profile.run() function.
203 Namespaces are internally managed to work correctly; profile.run
203 Namespaces are internally managed to work correctly; profile.run
204 cannot be used in IPython because it makes certain assumptions about
204 cannot be used in IPython because it makes certain assumptions about
205 namespaces which do not hold under IPython.
205 namespaces which do not hold under IPython.
206
206
207 Options:
207 Options:
208
208
209 -l <limit>
209 -l <limit>
210 you can place restrictions on what or how much of the
210 you can place restrictions on what or how much of the
211 profile gets printed. The limit value can be:
211 profile gets printed. The limit value can be:
212
212
213 * A string: only information for function names containing this string
213 * A string: only information for function names containing this string
214 is printed.
214 is printed.
215
215
216 * An integer: only these many lines are printed.
216 * An integer: only these many lines are printed.
217
217
218 * A float (between 0 and 1): this fraction of the report is printed
218 * A float (between 0 and 1): this fraction of the report is printed
219 (for example, use a limit of 0.4 to see the topmost 40% only).
219 (for example, use a limit of 0.4 to see the topmost 40% only).
220
220
221 You can combine several limits with repeated use of the option. For
221 You can combine several limits with repeated use of the option. For
222 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
222 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
223 information about class constructors.
223 information about class constructors.
224
224
225 -r
225 -r
226 return the pstats.Stats object generated by the profiling. This
226 return the pstats.Stats object generated by the profiling. This
227 object has all the information about the profile in it, and you can
227 object has all the information about the profile in it, and you can
228 later use it for further analysis or in other functions.
228 later use it for further analysis or in other functions.
229
229
230 -s <key>
230 -s <key>
231 sort profile by given key. You can provide more than one key
231 sort profile by given key. You can provide more than one key
232 by using the option several times: '-s key1 -s key2 -s key3...'. The
232 by using the option several times: '-s key1 -s key2 -s key3...'. The
233 default sorting key is 'time'.
233 default sorting key is 'time'.
234
234
235 The following is copied verbatim from the profile documentation
235 The following is copied verbatim from the profile documentation
236 referenced below:
236 referenced below:
237
237
238 When more than one key is provided, additional keys are used as
238 When more than one key is provided, additional keys are used as
239 secondary criteria when the there is equality in all keys selected
239 secondary criteria when the there is equality in all keys selected
240 before them.
240 before them.
241
241
242 Abbreviations can be used for any key names, as long as the
242 Abbreviations can be used for any key names, as long as the
243 abbreviation is unambiguous. The following are the keys currently
243 abbreviation is unambiguous. The following are the keys currently
244 defined:
244 defined:
245
245
246 ============ =====================
246 ============ =====================
247 Valid Arg Meaning
247 Valid Arg Meaning
248 ============ =====================
248 ============ =====================
249 "calls" call count
249 "calls" call count
250 "cumulative" cumulative time
250 "cumulative" cumulative time
251 "file" file name
251 "file" file name
252 "module" file name
252 "module" file name
253 "pcalls" primitive call count
253 "pcalls" primitive call count
254 "line" line number
254 "line" line number
255 "name" function name
255 "name" function name
256 "nfl" name/file/line
256 "nfl" name/file/line
257 "stdname" standard name
257 "stdname" standard name
258 "time" internal time
258 "time" internal time
259 ============ =====================
259 ============ =====================
260
260
261 Note that all sorts on statistics are in descending order (placing
261 Note that all sorts on statistics are in descending order (placing
262 most time consuming items first), where as name, file, and line number
262 most time consuming items first), where as name, file, and line number
263 searches are in ascending order (i.e., alphabetical). The subtle
263 searches are in ascending order (i.e., alphabetical). The subtle
264 distinction between "nfl" and "stdname" is that the standard name is a
264 distinction between "nfl" and "stdname" is that the standard name is a
265 sort of the name as printed, which means that the embedded line
265 sort of the name as printed, which means that the embedded line
266 numbers get compared in an odd way. For example, lines 3, 20, and 40
266 numbers get compared in an odd way. For example, lines 3, 20, and 40
267 would (if the file names were the same) appear in the string order
267 would (if the file names were the same) appear in the string order
268 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
268 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
269 line numbers. In fact, sort_stats("nfl") is the same as
269 line numbers. In fact, sort_stats("nfl") is the same as
270 sort_stats("name", "file", "line").
270 sort_stats("name", "file", "line").
271
271
272 -T <filename>
272 -T <filename>
273 save profile results as shown on screen to a text
273 save profile results as shown on screen to a text
274 file. The profile is still shown on screen.
274 file. The profile is still shown on screen.
275
275
276 -D <filename>
276 -D <filename>
277 save (via dump_stats) profile statistics to given
277 save (via dump_stats) profile statistics to given
278 filename. This data is in a format understood by the pstats module, and
278 filename. This data is in a format understood by the pstats module, and
279 is generated by a call to the dump_stats() method of profile
279 is generated by a call to the dump_stats() method of profile
280 objects. The profile is still shown on screen.
280 objects. The profile is still shown on screen.
281
281
282 -q
282 -q
283 suppress output to the pager. Best used with -T and/or -D above.
283 suppress output to the pager. Best used with -T and/or -D above.
284
284
285 If you want to run complete programs under the profiler's control, use
285 If you want to run complete programs under the profiler's control, use
286 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
286 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
287 contains profiler specific options as described here.
287 contains profiler specific options as described here.
288
288
289 You can read the complete documentation for the profile module with::
289 You can read the complete documentation for the profile module with::
290
290
291 In [1]: import profile; profile.help()
291 In [1]: import profile; profile.help()
292
292
293 .. versionchanged:: 7.3
293 .. versionchanged:: 7.3
294 User variables are no longer expanded,
294 User variables are no longer expanded,
295 the magic line is always left unmodified.
295 the magic line is always left unmodified.
296
296
297 """
297 """
298 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
298 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
299 list_all=True, posix=False)
299 list_all=True, posix=False)
300 if cell is not None:
300 if cell is not None:
301 arg_str += '\n' + cell
301 arg_str += '\n' + cell
302 arg_str = self.shell.transform_cell(arg_str)
302 arg_str = self.shell.transform_cell(arg_str)
303 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
303 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
304
304
305 def _run_with_profiler(self, code, opts, namespace):
305 def _run_with_profiler(self, code, opts, namespace):
306 """
306 """
307 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
307 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
308
308
309 Parameters
309 Parameters
310 ----------
310 ----------
311 code : str
311 code : str
312 Code to be executed.
312 Code to be executed.
313 opts : Struct
313 opts : Struct
314 Options parsed by `self.parse_options`.
314 Options parsed by `self.parse_options`.
315 namespace : dict
315 namespace : dict
316 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
316 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
317
317
318 """
318 """
319
319
320 # Fill default values for unspecified options:
320 # Fill default values for unspecified options:
321 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
321 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
322
322
323 prof = profile.Profile()
323 prof = profile.Profile()
324 try:
324 try:
325 prof = prof.runctx(code, namespace, namespace)
325 prof = prof.runctx(code, namespace, namespace)
326 sys_exit = ''
326 sys_exit = ''
327 except SystemExit:
327 except SystemExit:
328 sys_exit = """*** SystemExit exception caught in code being profiled."""
328 sys_exit = """*** SystemExit exception caught in code being profiled."""
329
329
330 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
330 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
331
331
332 lims = opts.l
332 lims = opts.l
333 if lims:
333 if lims:
334 lims = [] # rebuild lims with ints/floats/strings
334 lims = [] # rebuild lims with ints/floats/strings
335 for lim in opts.l:
335 for lim in opts.l:
336 try:
336 try:
337 lims.append(int(lim))
337 lims.append(int(lim))
338 except ValueError:
338 except ValueError:
339 try:
339 try:
340 lims.append(float(lim))
340 lims.append(float(lim))
341 except ValueError:
341 except ValueError:
342 lims.append(lim)
342 lims.append(lim)
343
343
344 # Trap output.
344 # Trap output.
345 stdout_trap = StringIO()
345 stdout_trap = StringIO()
346 stats_stream = stats.stream
346 stats_stream = stats.stream
347 try:
347 try:
348 stats.stream = stdout_trap
348 stats.stream = stdout_trap
349 stats.print_stats(*lims)
349 stats.print_stats(*lims)
350 finally:
350 finally:
351 stats.stream = stats_stream
351 stats.stream = stats_stream
352
352
353 output = stdout_trap.getvalue()
353 output = stdout_trap.getvalue()
354 output = output.rstrip()
354 output = output.rstrip()
355
355
356 if 'q' not in opts:
356 if 'q' not in opts:
357 page.page(output)
357 page.page(output)
358 print(sys_exit, end=' ')
358 print(sys_exit, end=' ')
359
359
360 dump_file = opts.D[0]
360 dump_file = opts.D[0]
361 text_file = opts.T[0]
361 text_file = opts.T[0]
362 if dump_file:
362 if dump_file:
363 prof.dump_stats(dump_file)
363 prof.dump_stats(dump_file)
364 print(
364 print(
365 f"\n*** Profile stats marshalled to file {repr(dump_file)}.{sys_exit}"
365 f"\n*** Profile stats marshalled to file {repr(dump_file)}.{sys_exit}"
366 )
366 )
367 if text_file:
367 if text_file:
368 pfile = Path(text_file)
368 pfile = Path(text_file)
369 pfile.touch(exist_ok=True)
369 pfile.touch(exist_ok=True)
370 pfile.write_text(output)
370 pfile.write_text(output)
371
371
372 print(
372 print(
373 f"\n*** Profile printout saved to text file {repr(text_file)}.{sys_exit}"
373 f"\n*** Profile printout saved to text file {repr(text_file)}.{sys_exit}"
374 )
374 )
375
375
376 if 'r' in opts:
376 if 'r' in opts:
377 return stats
377 return stats
378
378
379 return None
379 return None
380
380
381 @line_magic
381 @line_magic
382 def pdb(self, parameter_s=''):
382 def pdb(self, parameter_s=''):
383 """Control the automatic calling of the pdb interactive debugger.
383 """Control the automatic calling of the pdb interactive debugger.
384
384
385 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
385 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
386 argument it works as a toggle.
386 argument it works as a toggle.
387
387
388 When an exception is triggered, IPython can optionally call the
388 When an exception is triggered, IPython can optionally call the
389 interactive pdb debugger after the traceback printout. %pdb toggles
389 interactive pdb debugger after the traceback printout. %pdb toggles
390 this feature on and off.
390 this feature on and off.
391
391
392 The initial state of this feature is set in your configuration
392 The initial state of this feature is set in your configuration
393 file (the option is ``InteractiveShell.pdb``).
393 file (the option is ``InteractiveShell.pdb``).
394
394
395 If you want to just activate the debugger AFTER an exception has fired,
395 If you want to just activate the debugger AFTER an exception has fired,
396 without having to type '%pdb on' and rerunning your code, you can use
396 without having to type '%pdb on' and rerunning your code, you can use
397 the %debug magic."""
397 the %debug magic."""
398
398
399 par = parameter_s.strip().lower()
399 par = parameter_s.strip().lower()
400
400
401 if par:
401 if par:
402 try:
402 try:
403 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
403 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
404 except KeyError:
404 except KeyError:
405 print ('Incorrect argument. Use on/1, off/0, '
405 print ('Incorrect argument. Use on/1, off/0, '
406 'or nothing for a toggle.')
406 'or nothing for a toggle.')
407 return
407 return
408 else:
408 else:
409 # toggle
409 # toggle
410 new_pdb = not self.shell.call_pdb
410 new_pdb = not self.shell.call_pdb
411
411
412 # set on the shell
412 # set on the shell
413 self.shell.call_pdb = new_pdb
413 self.shell.call_pdb = new_pdb
414 print('Automatic pdb calling has been turned',on_off(new_pdb))
414 print('Automatic pdb calling has been turned',on_off(new_pdb))
415
415
416 @skip_doctest
416 @skip_doctest
417 @magic_arguments.magic_arguments()
417 @magic_arguments.magic_arguments()
418 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
418 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
419 help="""
419 help="""
420 Set break point at LINE in FILE.
420 Set break point at LINE in FILE.
421 """
421 """
422 )
422 )
423 @magic_arguments.argument('statement', nargs='*',
423 @magic_arguments.argument('statement', nargs='*',
424 help="""
424 help="""
425 Code to run in debugger.
425 Code to run in debugger.
426 You can omit this in cell magic mode.
426 You can omit this in cell magic mode.
427 """
427 """
428 )
428 )
429 @no_var_expand
429 @no_var_expand
430 @line_cell_magic
430 @line_cell_magic
431 def debug(self, line='', cell=None):
431 def debug(self, line='', cell=None):
432 """Activate the interactive debugger.
432 """Activate the interactive debugger.
433
433
434 This magic command support two ways of activating debugger.
434 This magic command support two ways of activating debugger.
435 One is to activate debugger before executing code. This way, you
435 One is to activate debugger before executing code. This way, you
436 can set a break point, to step through the code from the point.
436 can set a break point, to step through the code from the point.
437 You can use this mode by giving statements to execute and optionally
437 You can use this mode by giving statements to execute and optionally
438 a breakpoint.
438 a breakpoint.
439
439
440 The other one is to activate debugger in post-mortem mode. You can
440 The other one is to activate debugger in post-mortem mode. You can
441 activate this mode simply running %debug without any argument.
441 activate this mode simply running %debug without any argument.
442 If an exception has just occurred, this lets you inspect its stack
442 If an exception has just occurred, this lets you inspect its stack
443 frames interactively. Note that this will always work only on the last
443 frames interactively. Note that this will always work only on the last
444 traceback that occurred, so you must call this quickly after an
444 traceback that occurred, so you must call this quickly after an
445 exception that you wish to inspect has fired, because if another one
445 exception that you wish to inspect has fired, because if another one
446 occurs, it clobbers the previous one.
446 occurs, it clobbers the previous one.
447
447
448 If you want IPython to automatically do this on every exception, see
448 If you want IPython to automatically do this on every exception, see
449 the %pdb magic for more details.
449 the %pdb magic for more details.
450
450
451 .. versionchanged:: 7.3
451 .. versionchanged:: 7.3
452 When running code, user variables are no longer expanded,
452 When running code, user variables are no longer expanded,
453 the magic line is always left unmodified.
453 the magic line is always left unmodified.
454
454
455 """
455 """
456 args = magic_arguments.parse_argstring(self.debug, line)
456 args = magic_arguments.parse_argstring(self.debug, line)
457
457
458 if not (args.breakpoint or args.statement or cell):
458 if not (args.breakpoint or args.statement or cell):
459 self._debug_post_mortem()
459 self._debug_post_mortem()
460 elif not (args.breakpoint or cell):
460 elif not (args.breakpoint or cell):
461 # If there is no breakpoints, the line is just code to execute
461 # If there is no breakpoints, the line is just code to execute
462 self._debug_exec(line, None)
462 self._debug_exec(line, None)
463 else:
463 else:
464 # Here we try to reconstruct the code from the output of
464 # Here we try to reconstruct the code from the output of
465 # parse_argstring. This might not work if the code has spaces
465 # parse_argstring. This might not work if the code has spaces
466 # For example this fails for `print("a b")`
466 # For example this fails for `print("a b")`
467 code = "\n".join(args.statement)
467 code = "\n".join(args.statement)
468 if cell:
468 if cell:
469 code += "\n" + cell
469 code += "\n" + cell
470 self._debug_exec(code, args.breakpoint)
470 self._debug_exec(code, args.breakpoint)
471
471
472 def _debug_post_mortem(self):
472 def _debug_post_mortem(self):
473 self.shell.debugger(force=True)
473 self.shell.debugger(force=True)
474
474
475 def _debug_exec(self, code, breakpoint):
475 def _debug_exec(self, code, breakpoint):
476 if breakpoint:
476 if breakpoint:
477 (filename, bp_line) = breakpoint.rsplit(':', 1)
477 (filename, bp_line) = breakpoint.rsplit(':', 1)
478 bp_line = int(bp_line)
478 bp_line = int(bp_line)
479 else:
479 else:
480 (filename, bp_line) = (None, None)
480 (filename, bp_line) = (None, None)
481 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
481 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
482
482
483 @line_magic
483 @line_magic
484 def tb(self, s):
484 def tb(self, s):
485 """Print the last traceback.
485 """Print the last traceback.
486
486
487 Optionally, specify an exception reporting mode, tuning the
487 Optionally, specify an exception reporting mode, tuning the
488 verbosity of the traceback. By default the currently-active exception
488 verbosity of the traceback. By default the currently-active exception
489 mode is used. See %xmode for changing exception reporting modes.
489 mode is used. See %xmode for changing exception reporting modes.
490
490
491 Valid modes: Plain, Context, Verbose, and Minimal.
491 Valid modes: Plain, Context, Verbose, and Minimal.
492 """
492 """
493 interactive_tb = self.shell.InteractiveTB
493 interactive_tb = self.shell.InteractiveTB
494 if s:
494 if s:
495 # Switch exception reporting mode for this one call.
495 # Switch exception reporting mode for this one call.
496 # Ensure it is switched back.
496 # Ensure it is switched back.
497 def xmode_switch_err(name):
497 def xmode_switch_err(name):
498 warn('Error changing %s exception modes.\n%s' %
498 warn('Error changing %s exception modes.\n%s' %
499 (name,sys.exc_info()[1]))
499 (name,sys.exc_info()[1]))
500
500
501 new_mode = s.strip().capitalize()
501 new_mode = s.strip().capitalize()
502 original_mode = interactive_tb.mode
502 original_mode = interactive_tb.mode
503 try:
503 try:
504 try:
504 try:
505 interactive_tb.set_mode(mode=new_mode)
505 interactive_tb.set_mode(mode=new_mode)
506 except Exception:
506 except Exception:
507 xmode_switch_err('user')
507 xmode_switch_err('user')
508 else:
508 else:
509 self.shell.showtraceback()
509 self.shell.showtraceback()
510 finally:
510 finally:
511 interactive_tb.set_mode(mode=original_mode)
511 interactive_tb.set_mode(mode=original_mode)
512 else:
512 else:
513 self.shell.showtraceback()
513 self.shell.showtraceback()
514
514
515 @skip_doctest
515 @skip_doctest
516 @line_magic
516 @line_magic
517 def run(self, parameter_s='', runner=None,
517 def run(self, parameter_s='', runner=None,
518 file_finder=get_py_filename):
518 file_finder=get_py_filename):
519 """Run the named file inside IPython as a program.
519 """Run the named file inside IPython as a program.
520
520
521 Usage::
521 Usage::
522
522
523 %run [-n -i -e -G]
523 %run [-n -i -e -G]
524 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
524 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
525 ( -m mod | file ) [args]
525 ( -m mod | file ) [args]
526
526
527 Parameters after the filename are passed as command-line arguments to
527 Parameters after the filename are passed as command-line arguments to
528 the program (put in sys.argv). Then, control returns to IPython's
528 the program (put in sys.argv). Then, control returns to IPython's
529 prompt.
529 prompt.
530
530
531 This is similar to running at a system prompt ``python file args``,
531 This is similar to running at a system prompt ``python file args``,
532 but with the advantage of giving you IPython's tracebacks, and of
532 but with the advantage of giving you IPython's tracebacks, and of
533 loading all variables into your interactive namespace for further use
533 loading all variables into your interactive namespace for further use
534 (unless -p is used, see below).
534 (unless -p is used, see below).
535
535
536 The file is executed in a namespace initially consisting only of
536 The file is executed in a namespace initially consisting only of
537 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
537 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
538 sees its environment as if it were being run as a stand-alone program
538 sees its environment as if it were being run as a stand-alone program
539 (except for sharing global objects such as previously imported
539 (except for sharing global objects such as previously imported
540 modules). But after execution, the IPython interactive namespace gets
540 modules). But after execution, the IPython interactive namespace gets
541 updated with all variables defined in the program (except for __name__
541 updated with all variables defined in the program (except for __name__
542 and sys.argv). This allows for very convenient loading of code for
542 and sys.argv). This allows for very convenient loading of code for
543 interactive work, while giving each program a 'clean sheet' to run in.
543 interactive work, while giving each program a 'clean sheet' to run in.
544
544
545 Arguments are expanded using shell-like glob match. Patterns
545 Arguments are expanded using shell-like glob match. Patterns
546 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
546 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
547 tilde '~' will be expanded into user's home directory. Unlike
547 tilde '~' will be expanded into user's home directory. Unlike
548 real shells, quotation does not suppress expansions. Use
548 real shells, quotation does not suppress expansions. Use
549 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
549 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
550 To completely disable these expansions, you can use -G flag.
550 To completely disable these expansions, you can use -G flag.
551
551
552 On Windows systems, the use of single quotes `'` when specifying
552 On Windows systems, the use of single quotes `'` when specifying
553 a file is not supported. Use double quotes `"`.
553 a file is not supported. Use double quotes `"`.
554
554
555 Options:
555 Options:
556
556
557 -n
557 -n
558 __name__ is NOT set to '__main__', but to the running file's name
558 __name__ is NOT set to '__main__', but to the running file's name
559 without extension (as python does under import). This allows running
559 without extension (as python does under import). This allows running
560 scripts and reloading the definitions in them without calling code
560 scripts and reloading the definitions in them without calling code
561 protected by an ``if __name__ == "__main__"`` clause.
561 protected by an ``if __name__ == "__main__"`` clause.
562
562
563 -i
563 -i
564 run the file in IPython's namespace instead of an empty one. This
564 run the file in IPython's namespace instead of an empty one. This
565 is useful if you are experimenting with code written in a text editor
565 is useful if you are experimenting with code written in a text editor
566 which depends on variables defined interactively.
566 which depends on variables defined interactively.
567
567
568 -e
568 -e
569 ignore sys.exit() calls or SystemExit exceptions in the script
569 ignore sys.exit() calls or SystemExit exceptions in the script
570 being run. This is particularly useful if IPython is being used to
570 being run. This is particularly useful if IPython is being used to
571 run unittests, which always exit with a sys.exit() call. In such
571 run unittests, which always exit with a sys.exit() call. In such
572 cases you are interested in the output of the test results, not in
572 cases you are interested in the output of the test results, not in
573 seeing a traceback of the unittest module.
573 seeing a traceback of the unittest module.
574
574
575 -t
575 -t
576 print timing information at the end of the run. IPython will give
576 print timing information at the end of the run. IPython will give
577 you an estimated CPU time consumption for your script, which under
577 you an estimated CPU time consumption for your script, which under
578 Unix uses the resource module to avoid the wraparound problems of
578 Unix uses the resource module to avoid the wraparound problems of
579 time.clock(). Under Unix, an estimate of time spent on system tasks
579 time.clock(). Under Unix, an estimate of time spent on system tasks
580 is also given (for Windows platforms this is reported as 0.0).
580 is also given (for Windows platforms this is reported as 0.0).
581
581
582 If -t is given, an additional ``-N<N>`` option can be given, where <N>
582 If -t is given, an additional ``-N<N>`` option can be given, where <N>
583 must be an integer indicating how many times you want the script to
583 must be an integer indicating how many times you want the script to
584 run. The final timing report will include total and per run results.
584 run. The final timing report will include total and per run results.
585
585
586 For example (testing the script uniq_stable.py)::
586 For example (testing the script uniq_stable.py)::
587
587
588 In [1]: run -t uniq_stable
588 In [1]: run -t uniq_stable
589
589
590 IPython CPU timings (estimated):
590 IPython CPU timings (estimated):
591 User : 0.19597 s.
591 User : 0.19597 s.
592 System: 0.0 s.
592 System: 0.0 s.
593
593
594 In [2]: run -t -N5 uniq_stable
594 In [2]: run -t -N5 uniq_stable
595
595
596 IPython CPU timings (estimated):
596 IPython CPU timings (estimated):
597 Total runs performed: 5
597 Total runs performed: 5
598 Times : Total Per run
598 Times : Total Per run
599 User : 0.910862 s, 0.1821724 s.
599 User : 0.910862 s, 0.1821724 s.
600 System: 0.0 s, 0.0 s.
600 System: 0.0 s, 0.0 s.
601
601
602 -d
602 -d
603 run your program under the control of pdb, the Python debugger.
603 run your program under the control of pdb, the Python debugger.
604 This allows you to execute your program step by step, watch variables,
604 This allows you to execute your program step by step, watch variables,
605 etc. Internally, what IPython does is similar to calling::
605 etc. Internally, what IPython does is similar to calling::
606
606
607 pdb.run('execfile("YOURFILENAME")')
607 pdb.run('execfile("YOURFILENAME")')
608
608
609 with a breakpoint set on line 1 of your file. You can change the line
609 with a breakpoint set on line 1 of your file. You can change the line
610 number for this automatic breakpoint to be <N> by using the -bN option
610 number for this automatic breakpoint to be <N> by using the -bN option
611 (where N must be an integer). For example::
611 (where N must be an integer). For example::
612
612
613 %run -d -b40 myscript
613 %run -d -b40 myscript
614
614
615 will set the first breakpoint at line 40 in myscript.py. Note that
615 will set the first breakpoint at line 40 in myscript.py. Note that
616 the first breakpoint must be set on a line which actually does
616 the first breakpoint must be set on a line which actually does
617 something (not a comment or docstring) for it to stop execution.
617 something (not a comment or docstring) for it to stop execution.
618
618
619 Or you can specify a breakpoint in a different file::
619 Or you can specify a breakpoint in a different file::
620
620
621 %run -d -b myotherfile.py:20 myscript
621 %run -d -b myotherfile.py:20 myscript
622
622
623 When the pdb debugger starts, you will see a (Pdb) prompt. You must
623 When the pdb debugger starts, you will see a (Pdb) prompt. You must
624 first enter 'c' (without quotes) to start execution up to the first
624 first enter 'c' (without quotes) to start execution up to the first
625 breakpoint.
625 breakpoint.
626
626
627 Entering 'help' gives information about the use of the debugger. You
627 Entering 'help' gives information about the use of the debugger. You
628 can easily see pdb's full documentation with "import pdb;pdb.help()"
628 can easily see pdb's full documentation with "import pdb;pdb.help()"
629 at a prompt.
629 at a prompt.
630
630
631 -p
631 -p
632 run program under the control of the Python profiler module (which
632 run program under the control of the Python profiler module (which
633 prints a detailed report of execution times, function calls, etc).
633 prints a detailed report of execution times, function calls, etc).
634
634
635 You can pass other options after -p which affect the behavior of the
635 You can pass other options after -p which affect the behavior of the
636 profiler itself. See the docs for %prun for details.
636 profiler itself. See the docs for %prun for details.
637
637
638 In this mode, the program's variables do NOT propagate back to the
638 In this mode, the program's variables do NOT propagate back to the
639 IPython interactive namespace (because they remain in the namespace
639 IPython interactive namespace (because they remain in the namespace
640 where the profiler executes them).
640 where the profiler executes them).
641
641
642 Internally this triggers a call to %prun, see its documentation for
642 Internally this triggers a call to %prun, see its documentation for
643 details on the options available specifically for profiling.
643 details on the options available specifically for profiling.
644
644
645 There is one special usage for which the text above doesn't apply:
645 There is one special usage for which the text above doesn't apply:
646 if the filename ends with .ipy[nb], the file is run as ipython script,
646 if the filename ends with .ipy[nb], the file is run as ipython script,
647 just as if the commands were written on IPython prompt.
647 just as if the commands were written on IPython prompt.
648
648
649 -m
649 -m
650 specify module name to load instead of script path. Similar to
650 specify module name to load instead of script path. Similar to
651 the -m option for the python interpreter. Use this option last if you
651 the -m option for the python interpreter. Use this option last if you
652 want to combine with other %run options. Unlike the python interpreter
652 want to combine with other %run options. Unlike the python interpreter
653 only source modules are allowed no .pyc or .pyo files.
653 only source modules are allowed no .pyc or .pyo files.
654 For example::
654 For example::
655
655
656 %run -m example
656 %run -m example
657
657
658 will run the example module.
658 will run the example module.
659
659
660 -G
660 -G
661 disable shell-like glob expansion of arguments.
661 disable shell-like glob expansion of arguments.
662
662
663 """
663 """
664
664
665 # Logic to handle issue #3664
665 # Logic to handle issue #3664
666 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
666 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
667 if '-m' in parameter_s and '--' not in parameter_s:
667 if '-m' in parameter_s and '--' not in parameter_s:
668 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
668 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
669 for idx, arg in enumerate(argv):
669 for idx, arg in enumerate(argv):
670 if arg and arg.startswith('-') and arg != '-':
670 if arg and arg.startswith('-') and arg != '-':
671 if arg == '-m':
671 if arg == '-m':
672 argv.insert(idx + 2, '--')
672 argv.insert(idx + 2, '--')
673 break
673 break
674 else:
674 else:
675 # Positional arg, break
675 # Positional arg, break
676 break
676 break
677 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
677 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
678
678
679 # get arguments and set sys.argv for program to be run.
679 # get arguments and set sys.argv for program to be run.
680 opts, arg_lst = self.parse_options(parameter_s,
680 opts, arg_lst = self.parse_options(parameter_s,
681 'nidtN:b:pD:l:rs:T:em:G',
681 'nidtN:b:pD:l:rs:T:em:G',
682 mode='list', list_all=1)
682 mode='list', list_all=1)
683 if "m" in opts:
683 if "m" in opts:
684 modulename = opts["m"][0]
684 modulename = opts["m"][0]
685 modpath = find_mod(modulename)
685 modpath = find_mod(modulename)
686 if modpath is None:
686 if modpath is None:
687 msg = '%r is not a valid modulename on sys.path'%modulename
687 msg = '%r is not a valid modulename on sys.path'%modulename
688 raise Exception(msg)
688 raise Exception(msg)
689 arg_lst = [modpath] + arg_lst
689 arg_lst = [modpath] + arg_lst
690 try:
690 try:
691 fpath = None # initialize to make sure fpath is in scope later
691 fpath = None # initialize to make sure fpath is in scope later
692 fpath = arg_lst[0]
692 fpath = arg_lst[0]
693 filename = file_finder(fpath)
693 filename = file_finder(fpath)
694 except IndexError as e:
694 except IndexError as e:
695 msg = 'you must provide at least a filename.'
695 msg = 'you must provide at least a filename.'
696 raise Exception(msg) from e
696 raise Exception(msg) from e
697 except IOError as e:
697 except IOError as e:
698 try:
698 try:
699 msg = str(e)
699 msg = str(e)
700 except UnicodeError:
700 except UnicodeError:
701 msg = e.message
701 msg = e.message
702 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
702 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
703 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
703 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
704 raise Exception(msg) from e
704 raise Exception(msg) from e
705 except TypeError:
705 except TypeError:
706 if fpath in sys.meta_path:
706 if fpath in sys.meta_path:
707 filename = ""
707 filename = ""
708 else:
708 else:
709 raise
709 raise
710
710
711 if filename.lower().endswith(('.ipy', '.ipynb')):
711 if filename.lower().endswith(('.ipy', '.ipynb')):
712 with preserve_keys(self.shell.user_ns, '__file__'):
712 with preserve_keys(self.shell.user_ns, '__file__'):
713 self.shell.user_ns['__file__'] = filename
713 self.shell.user_ns['__file__'] = filename
714 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
714 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
715 return
715 return
716
716
717 # Control the response to exit() calls made by the script being run
717 # Control the response to exit() calls made by the script being run
718 exit_ignore = 'e' in opts
718 exit_ignore = 'e' in opts
719
719
720 # Make sure that the running script gets a proper sys.argv as if it
720 # Make sure that the running script gets a proper sys.argv as if it
721 # were run from a system shell.
721 # were run from a system shell.
722 save_argv = sys.argv # save it for later restoring
722 save_argv = sys.argv # save it for later restoring
723
723
724 if 'G' in opts:
724 if 'G' in opts:
725 args = arg_lst[1:]
725 args = arg_lst[1:]
726 else:
726 else:
727 # tilde and glob expansion
727 # tilde and glob expansion
728 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
728 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
729
729
730 sys.argv = [filename] + args # put in the proper filename
730 sys.argv = [filename] + args # put in the proper filename
731
731
732 if 'n' in opts:
732 if 'n' in opts:
733 name = Path(filename).stem
733 name = Path(filename).stem
734 else:
734 else:
735 name = '__main__'
735 name = '__main__'
736
736
737 if 'i' in opts:
737 if 'i' in opts:
738 # Run in user's interactive namespace
738 # Run in user's interactive namespace
739 prog_ns = self.shell.user_ns
739 prog_ns = self.shell.user_ns
740 __name__save = self.shell.user_ns['__name__']
740 __name__save = self.shell.user_ns['__name__']
741 prog_ns['__name__'] = name
741 prog_ns['__name__'] = name
742 main_mod = self.shell.user_module
742 main_mod = self.shell.user_module
743
743
744 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
744 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
745 # set the __file__ global in the script's namespace
745 # set the __file__ global in the script's namespace
746 # TK: Is this necessary in interactive mode?
746 # TK: Is this necessary in interactive mode?
747 prog_ns['__file__'] = filename
747 prog_ns['__file__'] = filename
748 else:
748 else:
749 # Run in a fresh, empty namespace
749 # Run in a fresh, empty namespace
750
750
751 # The shell MUST hold a reference to prog_ns so after %run
751 # The shell MUST hold a reference to prog_ns so after %run
752 # exits, the python deletion mechanism doesn't zero it out
752 # exits, the python deletion mechanism doesn't zero it out
753 # (leaving dangling references). See interactiveshell for details
753 # (leaving dangling references). See interactiveshell for details
754 main_mod = self.shell.new_main_mod(filename, name)
754 main_mod = self.shell.new_main_mod(filename, name)
755 prog_ns = main_mod.__dict__
755 prog_ns = main_mod.__dict__
756
756
757 # pickle fix. See interactiveshell for an explanation. But we need to
757 # pickle fix. See interactiveshell for an explanation. But we need to
758 # make sure that, if we overwrite __main__, we replace it at the end
758 # make sure that, if we overwrite __main__, we replace it at the end
759 main_mod_name = prog_ns['__name__']
759 main_mod_name = prog_ns['__name__']
760
760
761 if main_mod_name == '__main__':
761 if main_mod_name == '__main__':
762 restore_main = sys.modules['__main__']
762 restore_main = sys.modules['__main__']
763 else:
763 else:
764 restore_main = False
764 restore_main = False
765
765
766 # This needs to be undone at the end to prevent holding references to
766 # This needs to be undone at the end to prevent holding references to
767 # every single object ever created.
767 # every single object ever created.
768 sys.modules[main_mod_name] = main_mod
768 sys.modules[main_mod_name] = main_mod
769
769
770 if 'p' in opts or 'd' in opts:
770 if 'p' in opts or 'd' in opts:
771 if 'm' in opts:
771 if 'm' in opts:
772 code = 'run_module(modulename, prog_ns)'
772 code = 'run_module(modulename, prog_ns)'
773 code_ns = {
773 code_ns = {
774 'run_module': self.shell.safe_run_module,
774 'run_module': self.shell.safe_run_module,
775 'prog_ns': prog_ns,
775 'prog_ns': prog_ns,
776 'modulename': modulename,
776 'modulename': modulename,
777 }
777 }
778 else:
778 else:
779 if 'd' in opts:
779 if 'd' in opts:
780 # allow exceptions to raise in debug mode
780 # allow exceptions to raise in debug mode
781 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
781 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
782 else:
782 else:
783 code = 'execfile(filename, prog_ns)'
783 code = 'execfile(filename, prog_ns)'
784 code_ns = {
784 code_ns = {
785 'execfile': self.shell.safe_execfile,
785 'execfile': self.shell.safe_execfile,
786 'prog_ns': prog_ns,
786 'prog_ns': prog_ns,
787 'filename': get_py_filename(filename),
787 'filename': get_py_filename(filename),
788 }
788 }
789
789
790 try:
790 try:
791 stats = None
791 stats = None
792 if 'p' in opts:
792 if 'p' in opts:
793 stats = self._run_with_profiler(code, opts, code_ns)
793 stats = self._run_with_profiler(code, opts, code_ns)
794 else:
794 else:
795 if 'd' in opts:
795 if 'd' in opts:
796 bp_file, bp_line = parse_breakpoint(
796 bp_file, bp_line = parse_breakpoint(
797 opts.get('b', ['1'])[0], filename)
797 opts.get('b', ['1'])[0], filename)
798 self._run_with_debugger(
798 self._run_with_debugger(
799 code, code_ns, filename, bp_line, bp_file)
799 code, code_ns, filename, bp_line, bp_file)
800 else:
800 else:
801 if 'm' in opts:
801 if 'm' in opts:
802 def run():
802 def run():
803 self.shell.safe_run_module(modulename, prog_ns)
803 self.shell.safe_run_module(modulename, prog_ns)
804 else:
804 else:
805 if runner is None:
805 if runner is None:
806 runner = self.default_runner
806 runner = self.default_runner
807 if runner is None:
807 if runner is None:
808 runner = self.shell.safe_execfile
808 runner = self.shell.safe_execfile
809
809
810 def run():
810 def run():
811 runner(filename, prog_ns, prog_ns,
811 runner(filename, prog_ns, prog_ns,
812 exit_ignore=exit_ignore)
812 exit_ignore=exit_ignore)
813
813
814 if 't' in opts:
814 if 't' in opts:
815 # timed execution
815 # timed execution
816 try:
816 try:
817 nruns = int(opts['N'][0])
817 nruns = int(opts['N'][0])
818 if nruns < 1:
818 if nruns < 1:
819 error('Number of runs must be >=1')
819 error('Number of runs must be >=1')
820 return
820 return
821 except (KeyError):
821 except (KeyError):
822 nruns = 1
822 nruns = 1
823 self._run_with_timing(run, nruns)
823 self._run_with_timing(run, nruns)
824 else:
824 else:
825 # regular execution
825 # regular execution
826 run()
826 run()
827
827
828 if 'i' in opts:
828 if 'i' in opts:
829 self.shell.user_ns['__name__'] = __name__save
829 self.shell.user_ns['__name__'] = __name__save
830 else:
830 else:
831 # update IPython interactive namespace
831 # update IPython interactive namespace
832
832
833 # Some forms of read errors on the file may mean the
833 # Some forms of read errors on the file may mean the
834 # __name__ key was never set; using pop we don't have to
834 # __name__ key was never set; using pop we don't have to
835 # worry about a possible KeyError.
835 # worry about a possible KeyError.
836 prog_ns.pop('__name__', None)
836 prog_ns.pop('__name__', None)
837
837
838 with preserve_keys(self.shell.user_ns, '__file__'):
838 with preserve_keys(self.shell.user_ns, '__file__'):
839 self.shell.user_ns.update(prog_ns)
839 self.shell.user_ns.update(prog_ns)
840 finally:
840 finally:
841 # It's a bit of a mystery why, but __builtins__ can change from
841 # It's a bit of a mystery why, but __builtins__ can change from
842 # being a module to becoming a dict missing some key data after
842 # being a module to becoming a dict missing some key data after
843 # %run. As best I can see, this is NOT something IPython is doing
843 # %run. As best I can see, this is NOT something IPython is doing
844 # at all, and similar problems have been reported before:
844 # at all, and similar problems have been reported before:
845 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
845 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
846 # Since this seems to be done by the interpreter itself, the best
846 # Since this seems to be done by the interpreter itself, the best
847 # we can do is to at least restore __builtins__ for the user on
847 # we can do is to at least restore __builtins__ for the user on
848 # exit.
848 # exit.
849 self.shell.user_ns['__builtins__'] = builtin_mod
849 self.shell.user_ns['__builtins__'] = builtin_mod
850
850
851 # Ensure key global structures are restored
851 # Ensure key global structures are restored
852 sys.argv = save_argv
852 sys.argv = save_argv
853 if restore_main:
853 if restore_main:
854 sys.modules['__main__'] = restore_main
854 sys.modules['__main__'] = restore_main
855 if '__mp_main__' in sys.modules:
855 if '__mp_main__' in sys.modules:
856 sys.modules['__mp_main__'] = restore_main
856 sys.modules['__mp_main__'] = restore_main
857 else:
857 else:
858 # Remove from sys.modules the reference to main_mod we'd
858 # Remove from sys.modules the reference to main_mod we'd
859 # added. Otherwise it will trap references to objects
859 # added. Otherwise it will trap references to objects
860 # contained therein.
860 # contained therein.
861 del sys.modules[main_mod_name]
861 del sys.modules[main_mod_name]
862
862
863 return stats
863 return stats
864
864
865 def _run_with_debugger(self, code, code_ns, filename=None,
865 def _run_with_debugger(self, code, code_ns, filename=None,
866 bp_line=None, bp_file=None):
866 bp_line=None, bp_file=None):
867 """
867 """
868 Run `code` in debugger with a break point.
868 Run `code` in debugger with a break point.
869
869
870 Parameters
870 Parameters
871 ----------
871 ----------
872 code : str
872 code : str
873 Code to execute.
873 Code to execute.
874 code_ns : dict
874 code_ns : dict
875 A namespace in which `code` is executed.
875 A namespace in which `code` is executed.
876 filename : str
876 filename : str
877 `code` is ran as if it is in `filename`.
877 `code` is ran as if it is in `filename`.
878 bp_line : int, optional
878 bp_line : int, optional
879 Line number of the break point.
879 Line number of the break point.
880 bp_file : str, optional
880 bp_file : str, optional
881 Path to the file in which break point is specified.
881 Path to the file in which break point is specified.
882 `filename` is used if not given.
882 `filename` is used if not given.
883
883
884 Raises
884 Raises
885 ------
885 ------
886 UsageError
886 UsageError
887 If the break point given by `bp_line` is not valid.
887 If the break point given by `bp_line` is not valid.
888
888
889 """
889 """
890 deb = self.shell.InteractiveTB.pdb
890 deb = self.shell.InteractiveTB.pdb
891 if not deb:
891 if not deb:
892 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
892 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
893 deb = self.shell.InteractiveTB.pdb
893 deb = self.shell.InteractiveTB.pdb
894
894
895 # deb.checkline() fails if deb.curframe exists but is None; it can
895 # deb.checkline() fails if deb.curframe exists but is None; it can
896 # handle it not existing. https://github.com/ipython/ipython/issues/10028
896 # handle it not existing. https://github.com/ipython/ipython/issues/10028
897 if hasattr(deb, 'curframe'):
897 if hasattr(deb, 'curframe'):
898 del deb.curframe
898 del deb.curframe
899
899
900 # reset Breakpoint state, which is moronically kept
900 # reset Breakpoint state, which is moronically kept
901 # in a class
901 # in a class
902 bdb.Breakpoint.next = 1
902 bdb.Breakpoint.next = 1
903 bdb.Breakpoint.bplist = {}
903 bdb.Breakpoint.bplist = {}
904 bdb.Breakpoint.bpbynumber = [None]
904 bdb.Breakpoint.bpbynumber = [None]
905 deb.clear_all_breaks()
905 deb.clear_all_breaks()
906 if bp_line is not None:
906 if bp_line is not None:
907 # Set an initial breakpoint to stop execution
907 # Set an initial breakpoint to stop execution
908 maxtries = 10
908 maxtries = 10
909 bp_file = bp_file or filename
909 bp_file = bp_file or filename
910 checkline = deb.checkline(bp_file, bp_line)
910 checkline = deb.checkline(bp_file, bp_line)
911 if not checkline:
911 if not checkline:
912 for bp in range(bp_line + 1, bp_line + maxtries + 1):
912 for bp in range(bp_line + 1, bp_line + maxtries + 1):
913 if deb.checkline(bp_file, bp):
913 if deb.checkline(bp_file, bp):
914 break
914 break
915 else:
915 else:
916 msg = ("\nI failed to find a valid line to set "
916 msg = ("\nI failed to find a valid line to set "
917 "a breakpoint\n"
917 "a breakpoint\n"
918 "after trying up to line: %s.\n"
918 "after trying up to line: %s.\n"
919 "Please set a valid breakpoint manually "
919 "Please set a valid breakpoint manually "
920 "with the -b option." % bp)
920 "with the -b option." % bp)
921 raise UsageError(msg)
921 raise UsageError(msg)
922 # if we find a good linenumber, set the breakpoint
922 # if we find a good linenumber, set the breakpoint
923 deb.do_break('%s:%s' % (bp_file, bp_line))
923 deb.do_break('%s:%s' % (bp_file, bp_line))
924
924
925 if filename:
925 if filename:
926 # Mimic Pdb._runscript(...)
926 # Mimic Pdb._runscript(...)
927 deb._wait_for_mainpyfile = True
927 deb._wait_for_mainpyfile = True
928 deb.mainpyfile = deb.canonic(filename)
928 deb.mainpyfile = deb.canonic(filename)
929
929
930 # Start file run
930 # Start file run
931 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
931 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
932 try:
932 try:
933 if filename:
933 if filename:
934 # save filename so it can be used by methods on the deb object
934 # save filename so it can be used by methods on the deb object
935 deb._exec_filename = filename
935 deb._exec_filename = filename
936 while True:
936 while True:
937 try:
937 try:
938 trace = sys.gettrace()
938 trace = sys.gettrace()
939 deb.run(code, code_ns)
939 deb.run(code, code_ns)
940 except Restart:
940 except Restart:
941 print("Restarting")
941 print("Restarting")
942 if filename:
942 if filename:
943 deb._wait_for_mainpyfile = True
943 deb._wait_for_mainpyfile = True
944 deb.mainpyfile = deb.canonic(filename)
944 deb.mainpyfile = deb.canonic(filename)
945 continue
945 continue
946 else:
946 else:
947 break
947 break
948 finally:
948 finally:
949 sys.settrace(trace)
949 sys.settrace(trace)
950
950
951
951
952 except:
952 except:
953 etype, value, tb = sys.exc_info()
953 etype, value, tb = sys.exc_info()
954 # Skip three frames in the traceback: the %run one,
954 # Skip three frames in the traceback: the %run one,
955 # one inside bdb.py, and the command-line typed by the
955 # one inside bdb.py, and the command-line typed by the
956 # user (run by exec in pdb itself).
956 # user (run by exec in pdb itself).
957 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
957 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
958
958
959 @staticmethod
959 @staticmethod
960 def _run_with_timing(run, nruns):
960 def _run_with_timing(run, nruns):
961 """
961 """
962 Run function `run` and print timing information.
962 Run function `run` and print timing information.
963
963
964 Parameters
964 Parameters
965 ----------
965 ----------
966 run : callable
966 run : callable
967 Any callable object which takes no argument.
967 Any callable object which takes no argument.
968 nruns : int
968 nruns : int
969 Number of times to execute `run`.
969 Number of times to execute `run`.
970
970
971 """
971 """
972 twall0 = time.perf_counter()
972 twall0 = time.perf_counter()
973 if nruns == 1:
973 if nruns == 1:
974 t0 = clock2()
974 t0 = clock2()
975 run()
975 run()
976 t1 = clock2()
976 t1 = clock2()
977 t_usr = t1[0] - t0[0]
977 t_usr = t1[0] - t0[0]
978 t_sys = t1[1] - t0[1]
978 t_sys = t1[1] - t0[1]
979 print("\nIPython CPU timings (estimated):")
979 print("\nIPython CPU timings (estimated):")
980 print(" User : %10.2f s." % t_usr)
980 print(" User : %10.2f s." % t_usr)
981 print(" System : %10.2f s." % t_sys)
981 print(" System : %10.2f s." % t_sys)
982 else:
982 else:
983 runs = range(nruns)
983 runs = range(nruns)
984 t0 = clock2()
984 t0 = clock2()
985 for nr in runs:
985 for nr in runs:
986 run()
986 run()
987 t1 = clock2()
987 t1 = clock2()
988 t_usr = t1[0] - t0[0]
988 t_usr = t1[0] - t0[0]
989 t_sys = t1[1] - t0[1]
989 t_sys = t1[1] - t0[1]
990 print("\nIPython CPU timings (estimated):")
990 print("\nIPython CPU timings (estimated):")
991 print("Total runs performed:", nruns)
991 print("Total runs performed:", nruns)
992 print(" Times : %10s %10s" % ('Total', 'Per run'))
992 print(" Times : %10s %10s" % ('Total', 'Per run'))
993 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
993 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
994 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
994 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
995 twall1 = time.perf_counter()
995 twall1 = time.perf_counter()
996 print("Wall time: %10.2f s." % (twall1 - twall0))
996 print("Wall time: %10.2f s." % (twall1 - twall0))
997
997
998 @skip_doctest
998 @skip_doctest
999 @no_var_expand
999 @no_var_expand
1000 @line_cell_magic
1000 @line_cell_magic
1001 @needs_local_scope
1001 @needs_local_scope
1002 def timeit(self, line='', cell=None, local_ns=None):
1002 def timeit(self, line='', cell=None, local_ns=None):
1003 """Time execution of a Python statement or expression
1003 """Time execution of a Python statement or expression
1004
1004
1005 Usage, in line mode:
1005 Usage, in line mode:
1006 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1006 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1007 or in cell mode:
1007 or in cell mode:
1008 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1008 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1009 code
1009 code
1010 code...
1010 code...
1011
1011
1012 Time execution of a Python statement or expression using the timeit
1012 Time execution of a Python statement or expression using the timeit
1013 module. This function can be used both as a line and cell magic:
1013 module. This function can be used both as a line and cell magic:
1014
1014
1015 - In line mode you can time a single-line statement (though multiple
1015 - In line mode you can time a single-line statement (though multiple
1016 ones can be chained with using semicolons).
1016 ones can be chained with using semicolons).
1017
1017
1018 - In cell mode, the statement in the first line is used as setup code
1018 - In cell mode, the statement in the first line is used as setup code
1019 (executed but not timed) and the body of the cell is timed. The cell
1019 (executed but not timed) and the body of the cell is timed. The cell
1020 body has access to any variables created in the setup code.
1020 body has access to any variables created in the setup code.
1021
1021
1022 Options:
1022 Options:
1023 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1023 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1024 provided, <N> is determined so as to get sufficient accuracy.
1024 provided, <N> is determined so as to get sufficient accuracy.
1025
1025
1026 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1026 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1027 best result.
1027 best result.
1028 Default: 7
1028 Default: 7
1029
1029
1030 -t: use time.time to measure the time, which is the default on Unix.
1030 -t: use time.time to measure the time, which is the default on Unix.
1031 This function measures wall time.
1031 This function measures wall time.
1032
1032
1033 -c: use time.clock to measure the time, which is the default on
1033 -c: use time.clock to measure the time, which is the default on
1034 Windows and measures wall time. On Unix, resource.getrusage is used
1034 Windows and measures wall time. On Unix, resource.getrusage is used
1035 instead and returns the CPU user time.
1035 instead and returns the CPU user time.
1036
1036
1037 -p<P>: use a precision of <P> digits to display the timing result.
1037 -p<P>: use a precision of <P> digits to display the timing result.
1038 Default: 3
1038 Default: 3
1039
1039
1040 -q: Quiet, do not print result.
1040 -q: Quiet, do not print result.
1041
1041
1042 -o: return a TimeitResult that can be stored in a variable to inspect
1042 -o: return a TimeitResult that can be stored in a variable to inspect
1043 the result in more details.
1043 the result in more details.
1044
1044
1045 .. versionchanged:: 7.3
1045 .. versionchanged:: 7.3
1046 User variables are no longer expanded,
1046 User variables are no longer expanded,
1047 the magic line is always left unmodified.
1047 the magic line is always left unmodified.
1048
1048
1049 Examples
1049 Examples
1050 --------
1050 --------
1051 ::
1051 ::
1052
1052
1053 In [1]: %timeit pass
1053 In [1]: %timeit pass
1054 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
1054 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
1055
1055
1056 In [2]: u = None
1056 In [2]: u = None
1057
1057
1058 In [3]: %timeit u is None
1058 In [3]: %timeit u is None
1059 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
1059 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
1060
1060
1061 In [4]: %timeit -r 4 u == None
1061 In [4]: %timeit -r 4 u == None
1062
1062
1063 In [5]: import time
1063 In [5]: import time
1064
1064
1065 In [6]: %timeit -n1 time.sleep(2)
1065 In [6]: %timeit -n1 time.sleep(2)
1066
1066
1067
1067
1068 The times reported by %timeit will be slightly higher than those
1068 The times reported by %timeit will be slightly higher than those
1069 reported by the timeit.py script when variables are accessed. This is
1069 reported by the timeit.py script when variables are accessed. This is
1070 due to the fact that %timeit executes the statement in the namespace
1070 due to the fact that %timeit executes the statement in the namespace
1071 of the shell, compared with timeit.py, which uses a single setup
1071 of the shell, compared with timeit.py, which uses a single setup
1072 statement to import function or create variables. Generally, the bias
1072 statement to import function or create variables. Generally, the bias
1073 does not matter as long as results from timeit.py are not mixed with
1073 does not matter as long as results from timeit.py are not mixed with
1074 those from %timeit."""
1074 those from %timeit."""
1075
1075
1076 opts, stmt = self.parse_options(line, 'n:r:tcp:qo',
1076 opts, stmt = self.parse_options(
1077 posix=False, strict=False, preserve_non_opts=True)
1077 line, "n:r:tcp:qo", posix=False, strict=False, preserve_non_opts=True
1078 )
1078 if stmt == "" and cell is None:
1079 if stmt == "" and cell is None:
1079 return
1080 return
1080
1081
1081 timefunc = timeit.default_timer
1082 timefunc = timeit.default_timer
1082 number = int(getattr(opts, "n", 0))
1083 number = int(getattr(opts, "n", 0))
1083 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1084 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1084 repeat = int(getattr(opts, "r", default_repeat))
1085 repeat = int(getattr(opts, "r", default_repeat))
1085 precision = int(getattr(opts, "p", 3))
1086 precision = int(getattr(opts, "p", 3))
1086 quiet = 'q' in opts
1087 quiet = 'q' in opts
1087 return_result = 'o' in opts
1088 return_result = 'o' in opts
1088 if hasattr(opts, "t"):
1089 if hasattr(opts, "t"):
1089 timefunc = time.time
1090 timefunc = time.time
1090 if hasattr(opts, "c"):
1091 if hasattr(opts, "c"):
1091 timefunc = clock
1092 timefunc = clock
1092
1093
1093 timer = Timer(timer=timefunc)
1094 timer = Timer(timer=timefunc)
1094 # this code has tight coupling to the inner workings of timeit.Timer,
1095 # this code has tight coupling to the inner workings of timeit.Timer,
1095 # but is there a better way to achieve that the code stmt has access
1096 # but is there a better way to achieve that the code stmt has access
1096 # to the shell namespace?
1097 # to the shell namespace?
1097 transform = self.shell.transform_cell
1098 transform = self.shell.transform_cell
1098
1099
1099 if cell is None:
1100 if cell is None:
1100 # called as line magic
1101 # called as line magic
1101 ast_setup = self.shell.compile.ast_parse("pass")
1102 ast_setup = self.shell.compile.ast_parse("pass")
1102 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1103 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1103 else:
1104 else:
1104 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1105 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1105 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1106 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1106
1107
1107 ast_setup = self.shell.transform_ast(ast_setup)
1108 ast_setup = self.shell.transform_ast(ast_setup)
1108 ast_stmt = self.shell.transform_ast(ast_stmt)
1109 ast_stmt = self.shell.transform_ast(ast_stmt)
1109
1110
1110 # Check that these compile to valid Python code *outside* the timer func
1111 # Check that these compile to valid Python code *outside* the timer func
1111 # Invalid code may become valid when put inside the function & loop,
1112 # Invalid code may become valid when put inside the function & loop,
1112 # which messes up error messages.
1113 # which messes up error messages.
1113 # https://github.com/ipython/ipython/issues/10636
1114 # https://github.com/ipython/ipython/issues/10636
1114 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1115 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1115 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1116 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1116
1117
1117 # This codestring is taken from timeit.template - we fill it in as an
1118 # This codestring is taken from timeit.template - we fill it in as an
1118 # AST, so that we can apply our AST transformations to the user code
1119 # AST, so that we can apply our AST transformations to the user code
1119 # without affecting the timing code.
1120 # without affecting the timing code.
1120 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1121 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1121 ' setup\n'
1122 ' setup\n'
1122 ' _t0 = _timer()\n'
1123 ' _t0 = _timer()\n'
1123 ' for _i in _it:\n'
1124 ' for _i in _it:\n'
1124 ' stmt\n'
1125 ' stmt\n'
1125 ' _t1 = _timer()\n'
1126 ' _t1 = _timer()\n'
1126 ' return _t1 - _t0\n')
1127 ' return _t1 - _t0\n')
1127
1128
1128 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1129 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1129 timeit_ast = ast.fix_missing_locations(timeit_ast)
1130 timeit_ast = ast.fix_missing_locations(timeit_ast)
1130
1131
1131 # Track compilation time so it can be reported if too long
1132 # Track compilation time so it can be reported if too long
1132 # Minimum time above which compilation time will be reported
1133 # Minimum time above which compilation time will be reported
1133 tc_min = 0.1
1134 tc_min = 0.1
1134
1135
1135 t0 = clock()
1136 t0 = clock()
1136 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1137 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1137 tc = clock()-t0
1138 tc = clock()-t0
1138
1139
1139 ns = {}
1140 ns = {}
1140 glob = self.shell.user_ns
1141 glob = self.shell.user_ns
1141 # handles global vars with same name as local vars. We store them in conflict_globs.
1142 # handles global vars with same name as local vars. We store them in conflict_globs.
1142 conflict_globs = {}
1143 conflict_globs = {}
1143 if local_ns and cell is None:
1144 if local_ns and cell is None:
1144 for var_name, var_val in glob.items():
1145 for var_name, var_val in glob.items():
1145 if var_name in local_ns:
1146 if var_name in local_ns:
1146 conflict_globs[var_name] = var_val
1147 conflict_globs[var_name] = var_val
1147 glob.update(local_ns)
1148 glob.update(local_ns)
1148
1149
1149 exec(code, glob, ns)
1150 exec(code, glob, ns)
1150 timer.inner = ns["inner"]
1151 timer.inner = ns["inner"]
1151
1152
1152 # This is used to check if there is a huge difference between the
1153 # This is used to check if there is a huge difference between the
1153 # best and worst timings.
1154 # best and worst timings.
1154 # Issue: https://github.com/ipython/ipython/issues/6471
1155 # Issue: https://github.com/ipython/ipython/issues/6471
1155 if number == 0:
1156 if number == 0:
1156 # determine number so that 0.2 <= total time < 2.0
1157 # determine number so that 0.2 <= total time < 2.0
1157 for index in range(0, 10):
1158 for index in range(0, 10):
1158 number = 10 ** index
1159 number = 10 ** index
1159 time_number = timer.timeit(number)
1160 time_number = timer.timeit(number)
1160 if time_number >= 0.2:
1161 if time_number >= 0.2:
1161 break
1162 break
1162
1163
1163 all_runs = timer.repeat(repeat, number)
1164 all_runs = timer.repeat(repeat, number)
1164 best = min(all_runs) / number
1165 best = min(all_runs) / number
1165 worst = max(all_runs) / number
1166 worst = max(all_runs) / number
1166 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1167 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1167
1168
1168 # Restore global vars from conflict_globs
1169 # Restore global vars from conflict_globs
1169 if conflict_globs:
1170 if conflict_globs:
1170 glob.update(conflict_globs)
1171 glob.update(conflict_globs)
1171
1172
1172 if not quiet :
1173 if not quiet :
1173 # Check best timing is greater than zero to avoid a
1174 # Check best timing is greater than zero to avoid a
1174 # ZeroDivisionError.
1175 # ZeroDivisionError.
1175 # In cases where the slowest timing is lesser than a microsecond
1176 # In cases where the slowest timing is lesser than a microsecond
1176 # we assume that it does not really matter if the fastest
1177 # we assume that it does not really matter if the fastest
1177 # timing is 4 times faster than the slowest timing or not.
1178 # timing is 4 times faster than the slowest timing or not.
1178 if worst > 4 * best and best > 0 and worst > 1e-6:
1179 if worst > 4 * best and best > 0 and worst > 1e-6:
1179 print("The slowest run took %0.2f times longer than the "
1180 print("The slowest run took %0.2f times longer than the "
1180 "fastest. This could mean that an intermediate result "
1181 "fastest. This could mean that an intermediate result "
1181 "is being cached." % (worst / best))
1182 "is being cached." % (worst / best))
1182
1183
1183 print( timeit_result )
1184 print( timeit_result )
1184
1185
1185 if tc > tc_min:
1186 if tc > tc_min:
1186 print("Compiler time: %.2f s" % tc)
1187 print("Compiler time: %.2f s" % tc)
1187 if return_result:
1188 if return_result:
1188 return timeit_result
1189 return timeit_result
1189
1190
1190 @skip_doctest
1191 @skip_doctest
1191 @no_var_expand
1192 @no_var_expand
1192 @needs_local_scope
1193 @needs_local_scope
1193 @line_cell_magic
1194 @line_cell_magic
1194 def time(self,line='', cell=None, local_ns=None):
1195 def time(self,line='', cell=None, local_ns=None):
1195 """Time execution of a Python statement or expression.
1196 """Time execution of a Python statement or expression.
1196
1197
1197 The CPU and wall clock times are printed, and the value of the
1198 The CPU and wall clock times are printed, and the value of the
1198 expression (if any) is returned. Note that under Win32, system time
1199 expression (if any) is returned. Note that under Win32, system time
1199 is always reported as 0, since it can not be measured.
1200 is always reported as 0, since it can not be measured.
1200
1201
1201 This function can be used both as a line and cell magic:
1202 This function can be used both as a line and cell magic:
1202
1203
1203 - In line mode you can time a single-line statement (though multiple
1204 - In line mode you can time a single-line statement (though multiple
1204 ones can be chained with using semicolons).
1205 ones can be chained with using semicolons).
1205
1206
1206 - In cell mode, you can time the cell body (a directly
1207 - In cell mode, you can time the cell body (a directly
1207 following statement raises an error).
1208 following statement raises an error).
1208
1209
1209 This function provides very basic timing functionality. Use the timeit
1210 This function provides very basic timing functionality. Use the timeit
1210 magic for more control over the measurement.
1211 magic for more control over the measurement.
1211
1212
1212 .. versionchanged:: 7.3
1213 .. versionchanged:: 7.3
1213 User variables are no longer expanded,
1214 User variables are no longer expanded,
1214 the magic line is always left unmodified.
1215 the magic line is always left unmodified.
1215
1216
1216 Examples
1217 Examples
1217 --------
1218 --------
1218 ::
1219 ::
1219
1220
1220 In [1]: %time 2**128
1221 In [1]: %time 2**128
1221 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1222 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1222 Wall time: 0.00
1223 Wall time: 0.00
1223 Out[1]: 340282366920938463463374607431768211456L
1224 Out[1]: 340282366920938463463374607431768211456L
1224
1225
1225 In [2]: n = 1000000
1226 In [2]: n = 1000000
1226
1227
1227 In [3]: %time sum(range(n))
1228 In [3]: %time sum(range(n))
1228 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1229 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1229 Wall time: 1.37
1230 Wall time: 1.37
1230 Out[3]: 499999500000L
1231 Out[3]: 499999500000L
1231
1232
1232 In [4]: %time print 'hello world'
1233 In [4]: %time print 'hello world'
1233 hello world
1234 hello world
1234 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1235 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1235 Wall time: 0.00
1236 Wall time: 0.00
1236
1237
1237 Note that the time needed by Python to compile the given expression
1238 Note that the time needed by Python to compile the given expression
1238 will be reported if it is more than 0.1s. In this example, the
1239 will be reported if it is more than 0.1s. In this example, the
1239 actual exponentiation is done by Python at compilation time, so while
1240 actual exponentiation is done by Python at compilation time, so while
1240 the expression can take a noticeable amount of time to compute, that
1241 the expression can take a noticeable amount of time to compute, that
1241 time is purely due to the compilation:
1242 time is purely due to the compilation:
1242
1243
1243 In [5]: %time 3**9999;
1244 In [5]: %time 3**9999;
1244 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1245 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1245 Wall time: 0.00 s
1246 Wall time: 0.00 s
1246
1247
1247 In [6]: %time 3**999999;
1248 In [6]: %time 3**999999;
1248 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1249 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1249 Wall time: 0.00 s
1250 Wall time: 0.00 s
1250 Compiler : 0.78 s
1251 Compiler : 0.78 s
1251 """
1252 """
1252
1253
1253 # fail immediately if the given expression can't be compiled
1254 # fail immediately if the given expression can't be compiled
1254
1255
1255 if line and cell:
1256 if line and cell:
1256 raise UsageError("Can't use statement directly after '%%time'!")
1257 raise UsageError("Can't use statement directly after '%%time'!")
1257
1258
1258 if cell:
1259 if cell:
1259 expr = self.shell.transform_cell(cell)
1260 expr = self.shell.transform_cell(cell)
1260 else:
1261 else:
1261 expr = self.shell.transform_cell(line)
1262 expr = self.shell.transform_cell(line)
1262
1263
1263 # Minimum time above which parse time will be reported
1264 # Minimum time above which parse time will be reported
1264 tp_min = 0.1
1265 tp_min = 0.1
1265
1266
1266 t0 = clock()
1267 t0 = clock()
1267 expr_ast = self.shell.compile.ast_parse(expr)
1268 expr_ast = self.shell.compile.ast_parse(expr)
1268 tp = clock()-t0
1269 tp = clock()-t0
1269
1270
1270 # Apply AST transformations
1271 # Apply AST transformations
1271 expr_ast = self.shell.transform_ast(expr_ast)
1272 expr_ast = self.shell.transform_ast(expr_ast)
1272
1273
1273 # Minimum time above which compilation time will be reported
1274 # Minimum time above which compilation time will be reported
1274 tc_min = 0.1
1275 tc_min = 0.1
1275
1276
1276 expr_val=None
1277 expr_val=None
1277 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1278 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1278 mode = 'eval'
1279 mode = 'eval'
1279 source = '<timed eval>'
1280 source = '<timed eval>'
1280 expr_ast = ast.Expression(expr_ast.body[0].value)
1281 expr_ast = ast.Expression(expr_ast.body[0].value)
1281 else:
1282 else:
1282 mode = 'exec'
1283 mode = 'exec'
1283 source = '<timed exec>'
1284 source = '<timed exec>'
1284 # multi-line %%time case
1285 # multi-line %%time case
1285 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1286 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1286 expr_val= expr_ast.body[-1]
1287 expr_val= expr_ast.body[-1]
1287 expr_ast = expr_ast.body[:-1]
1288 expr_ast = expr_ast.body[:-1]
1288 expr_ast = Module(expr_ast, [])
1289 expr_ast = Module(expr_ast, [])
1289 expr_val = ast.Expression(expr_val.value)
1290 expr_val = ast.Expression(expr_val.value)
1290
1291
1291 t0 = clock()
1292 t0 = clock()
1292 code = self.shell.compile(expr_ast, source, mode)
1293 code = self.shell.compile(expr_ast, source, mode)
1293 tc = clock()-t0
1294 tc = clock()-t0
1294
1295
1295 # skew measurement as little as possible
1296 # skew measurement as little as possible
1296 glob = self.shell.user_ns
1297 glob = self.shell.user_ns
1297 wtime = time.time
1298 wtime = time.time
1298 # time execution
1299 # time execution
1299 wall_st = wtime()
1300 wall_st = wtime()
1300 if mode=='eval':
1301 if mode=='eval':
1301 st = clock2()
1302 st = clock2()
1302 try:
1303 try:
1303 out = eval(code, glob, local_ns)
1304 out = eval(code, glob, local_ns)
1304 except:
1305 except:
1305 self.shell.showtraceback()
1306 self.shell.showtraceback()
1306 return
1307 return
1307 end = clock2()
1308 end = clock2()
1308 else:
1309 else:
1309 st = clock2()
1310 st = clock2()
1310 try:
1311 try:
1311 exec(code, glob, local_ns)
1312 exec(code, glob, local_ns)
1312 out=None
1313 out=None
1313 # multi-line %%time case
1314 # multi-line %%time case
1314 if expr_val is not None:
1315 if expr_val is not None:
1315 code_2 = self.shell.compile(expr_val, source, 'eval')
1316 code_2 = self.shell.compile(expr_val, source, 'eval')
1316 out = eval(code_2, glob, local_ns)
1317 out = eval(code_2, glob, local_ns)
1317 except:
1318 except:
1318 self.shell.showtraceback()
1319 self.shell.showtraceback()
1319 return
1320 return
1320 end = clock2()
1321 end = clock2()
1321
1322
1322 wall_end = wtime()
1323 wall_end = wtime()
1323 # Compute actual times and report
1324 # Compute actual times and report
1324 wall_time = wall_end-wall_st
1325 wall_time = wall_end-wall_st
1325 cpu_user = end[0]-st[0]
1326 cpu_user = end[0]-st[0]
1326 cpu_sys = end[1]-st[1]
1327 cpu_sys = end[1]-st[1]
1327 cpu_tot = cpu_user+cpu_sys
1328 cpu_tot = cpu_user+cpu_sys
1328 # On windows cpu_sys is always zero, so no new information to the next print
1329 # On windows cpu_sys is always zero, so no new information to the next print
1329 if sys.platform != 'win32':
1330 if sys.platform != 'win32':
1330 print("CPU times: user %s, sys: %s, total: %s" % \
1331 print("CPU times: user %s, sys: %s, total: %s" % \
1331 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1332 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1332 print("Wall time: %s" % _format_time(wall_time))
1333 print("Wall time: %s" % _format_time(wall_time))
1333 if tc > tc_min:
1334 if tc > tc_min:
1334 print("Compiler : %s" % _format_time(tc))
1335 print("Compiler : %s" % _format_time(tc))
1335 if tp > tp_min:
1336 if tp > tp_min:
1336 print("Parser : %s" % _format_time(tp))
1337 print("Parser : %s" % _format_time(tp))
1337 return out
1338 return out
1338
1339
1339 @skip_doctest
1340 @skip_doctest
1340 @line_magic
1341 @line_magic
1341 def macro(self, parameter_s=''):
1342 def macro(self, parameter_s=''):
1342 """Define a macro for future re-execution. It accepts ranges of history,
1343 """Define a macro for future re-execution. It accepts ranges of history,
1343 filenames or string objects.
1344 filenames or string objects.
1344
1345
1345 Usage:\\
1346 Usage:\\
1346 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1347 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1347
1348
1348 Options:
1349 Options:
1349
1350
1350 -r: use 'raw' input. By default, the 'processed' history is used,
1351 -r: use 'raw' input. By default, the 'processed' history is used,
1351 so that magics are loaded in their transformed version to valid
1352 so that magics are loaded in their transformed version to valid
1352 Python. If this option is given, the raw input as typed at the
1353 Python. If this option is given, the raw input as typed at the
1353 command line is used instead.
1354 command line is used instead.
1354
1355
1355 -q: quiet macro definition. By default, a tag line is printed
1356 -q: quiet macro definition. By default, a tag line is printed
1356 to indicate the macro has been created, and then the contents of
1357 to indicate the macro has been created, and then the contents of
1357 the macro are printed. If this option is given, then no printout
1358 the macro are printed. If this option is given, then no printout
1358 is produced once the macro is created.
1359 is produced once the macro is created.
1359
1360
1360 This will define a global variable called `name` which is a string
1361 This will define a global variable called `name` which is a string
1361 made of joining the slices and lines you specify (n1,n2,... numbers
1362 made of joining the slices and lines you specify (n1,n2,... numbers
1362 above) from your input history into a single string. This variable
1363 above) from your input history into a single string. This variable
1363 acts like an automatic function which re-executes those lines as if
1364 acts like an automatic function which re-executes those lines as if
1364 you had typed them. You just type 'name' at the prompt and the code
1365 you had typed them. You just type 'name' at the prompt and the code
1365 executes.
1366 executes.
1366
1367
1367 The syntax for indicating input ranges is described in %history.
1368 The syntax for indicating input ranges is described in %history.
1368
1369
1369 Note: as a 'hidden' feature, you can also use traditional python slice
1370 Note: as a 'hidden' feature, you can also use traditional python slice
1370 notation, where N:M means numbers N through M-1.
1371 notation, where N:M means numbers N through M-1.
1371
1372
1372 For example, if your history contains (print using %hist -n )::
1373 For example, if your history contains (print using %hist -n )::
1373
1374
1374 44: x=1
1375 44: x=1
1375 45: y=3
1376 45: y=3
1376 46: z=x+y
1377 46: z=x+y
1377 47: print x
1378 47: print x
1378 48: a=5
1379 48: a=5
1379 49: print 'x',x,'y',y
1380 49: print 'x',x,'y',y
1380
1381
1381 you can create a macro with lines 44 through 47 (included) and line 49
1382 you can create a macro with lines 44 through 47 (included) and line 49
1382 called my_macro with::
1383 called my_macro with::
1383
1384
1384 In [55]: %macro my_macro 44-47 49
1385 In [55]: %macro my_macro 44-47 49
1385
1386
1386 Now, typing `my_macro` (without quotes) will re-execute all this code
1387 Now, typing `my_macro` (without quotes) will re-execute all this code
1387 in one pass.
1388 in one pass.
1388
1389
1389 You don't need to give the line-numbers in order, and any given line
1390 You don't need to give the line-numbers in order, and any given line
1390 number can appear multiple times. You can assemble macros with any
1391 number can appear multiple times. You can assemble macros with any
1391 lines from your input history in any order.
1392 lines from your input history in any order.
1392
1393
1393 The macro is a simple object which holds its value in an attribute,
1394 The macro is a simple object which holds its value in an attribute,
1394 but IPython's display system checks for macros and executes them as
1395 but IPython's display system checks for macros and executes them as
1395 code instead of printing them when you type their name.
1396 code instead of printing them when you type their name.
1396
1397
1397 You can view a macro's contents by explicitly printing it with::
1398 You can view a macro's contents by explicitly printing it with::
1398
1399
1399 print macro_name
1400 print macro_name
1400
1401
1401 """
1402 """
1402 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1403 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1403 if not args: # List existing macros
1404 if not args: # List existing macros
1404 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1405 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1405 if len(args) == 1:
1406 if len(args) == 1:
1406 raise UsageError(
1407 raise UsageError(
1407 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1408 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1408 name, codefrom = args[0], " ".join(args[1:])
1409 name, codefrom = args[0], " ".join(args[1:])
1409
1410
1410 #print 'rng',ranges # dbg
1411 #print 'rng',ranges # dbg
1411 try:
1412 try:
1412 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1413 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1413 except (ValueError, TypeError) as e:
1414 except (ValueError, TypeError) as e:
1414 print(e.args[0])
1415 print(e.args[0])
1415 return
1416 return
1416 macro = Macro(lines)
1417 macro = Macro(lines)
1417 self.shell.define_macro(name, macro)
1418 self.shell.define_macro(name, macro)
1418 if not ( 'q' in opts) :
1419 if not ( 'q' in opts) :
1419 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1420 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1420 print('=== Macro contents: ===')
1421 print('=== Macro contents: ===')
1421 print(macro, end=' ')
1422 print(macro, end=' ')
1422
1423
1423 @magic_arguments.magic_arguments()
1424 @magic_arguments.magic_arguments()
1424 @magic_arguments.argument('output', type=str, default='', nargs='?',
1425 @magic_arguments.argument('output', type=str, default='', nargs='?',
1425 help="""The name of the variable in which to store output.
1426 help="""The name of the variable in which to store output.
1426 This is a utils.io.CapturedIO object with stdout/err attributes
1427 This is a utils.io.CapturedIO object with stdout/err attributes
1427 for the text of the captured output.
1428 for the text of the captured output.
1428
1429
1429 CapturedOutput also has a show() method for displaying the output,
1430 CapturedOutput also has a show() method for displaying the output,
1430 and __call__ as well, so you can use that to quickly display the
1431 and __call__ as well, so you can use that to quickly display the
1431 output.
1432 output.
1432
1433
1433 If unspecified, captured output is discarded.
1434 If unspecified, captured output is discarded.
1434 """
1435 """
1435 )
1436 )
1436 @magic_arguments.argument('--no-stderr', action="store_true",
1437 @magic_arguments.argument('--no-stderr', action="store_true",
1437 help="""Don't capture stderr."""
1438 help="""Don't capture stderr."""
1438 )
1439 )
1439 @magic_arguments.argument('--no-stdout', action="store_true",
1440 @magic_arguments.argument('--no-stdout', action="store_true",
1440 help="""Don't capture stdout."""
1441 help="""Don't capture stdout."""
1441 )
1442 )
1442 @magic_arguments.argument('--no-display', action="store_true",
1443 @magic_arguments.argument('--no-display', action="store_true",
1443 help="""Don't capture IPython's rich display."""
1444 help="""Don't capture IPython's rich display."""
1444 )
1445 )
1445 @cell_magic
1446 @cell_magic
1446 def capture(self, line, cell):
1447 def capture(self, line, cell):
1447 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1448 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1448 args = magic_arguments.parse_argstring(self.capture, line)
1449 args = magic_arguments.parse_argstring(self.capture, line)
1449 out = not args.no_stdout
1450 out = not args.no_stdout
1450 err = not args.no_stderr
1451 err = not args.no_stderr
1451 disp = not args.no_display
1452 disp = not args.no_display
1452 with capture_output(out, err, disp) as io:
1453 with capture_output(out, err, disp) as io:
1453 self.shell.run_cell(cell)
1454 self.shell.run_cell(cell)
1454 if args.output:
1455 if args.output:
1455 self.shell.user_ns[args.output] = io
1456 self.shell.user_ns[args.output] = io
1456
1457
1457 def parse_breakpoint(text, current_file):
1458 def parse_breakpoint(text, current_file):
1458 '''Returns (file, line) for file:line and (current_file, line) for line'''
1459 '''Returns (file, line) for file:line and (current_file, line) for line'''
1459 colon = text.find(':')
1460 colon = text.find(':')
1460 if colon == -1:
1461 if colon == -1:
1461 return current_file, int(text)
1462 return current_file, int(text)
1462 else:
1463 else:
1463 return text[:colon], int(text[colon+1:])
1464 return text[:colon], int(text[colon+1:])
1464
1465
1465 def _format_time(timespan, precision=3):
1466 def _format_time(timespan, precision=3):
1466 """Formats the timespan in a human readable form"""
1467 """Formats the timespan in a human readable form"""
1467
1468
1468 if timespan >= 60.0:
1469 if timespan >= 60.0:
1469 # we have more than a minute, format that in a human readable form
1470 # we have more than a minute, format that in a human readable form
1470 # Idea from http://snipplr.com/view/5713/
1471 # Idea from http://snipplr.com/view/5713/
1471 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1472 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1472 time = []
1473 time = []
1473 leftover = timespan
1474 leftover = timespan
1474 for suffix, length in parts:
1475 for suffix, length in parts:
1475 value = int(leftover / length)
1476 value = int(leftover / length)
1476 if value > 0:
1477 if value > 0:
1477 leftover = leftover % length
1478 leftover = leftover % length
1478 time.append(u'%s%s' % (str(value), suffix))
1479 time.append(u'%s%s' % (str(value), suffix))
1479 if leftover < 1:
1480 if leftover < 1:
1480 break
1481 break
1481 return " ".join(time)
1482 return " ".join(time)
1482
1483
1483
1484
1484 # Unfortunately the unicode 'micro' symbol can cause problems in
1485 # Unfortunately the unicode 'micro' symbol can cause problems in
1485 # certain terminals.
1486 # certain terminals.
1486 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1487 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1487 # Try to prevent crashes by being more secure than it needs to
1488 # Try to prevent crashes by being more secure than it needs to
1488 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1489 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1489 units = [u"s", u"ms",u'us',"ns"] # the save value
1490 units = [u"s", u"ms",u'us',"ns"] # the save value
1490 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1491 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1491 try:
1492 try:
1492 u'\xb5'.encode(sys.stdout.encoding)
1493 u'\xb5'.encode(sys.stdout.encoding)
1493 units = [u"s", u"ms",u'\xb5s',"ns"]
1494 units = [u"s", u"ms",u'\xb5s',"ns"]
1494 except:
1495 except:
1495 pass
1496 pass
1496 scaling = [1, 1e3, 1e6, 1e9]
1497 scaling = [1, 1e3, 1e6, 1e9]
1497
1498
1498 if timespan > 0.0:
1499 if timespan > 0.0:
1499 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1500 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1500 else:
1501 else:
1501 order = 3
1502 order = 3
1502 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1503 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,1276 +1,1278 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for various magic functions.
2 """Tests for various magic functions.
3
3
4 Needs to be run by nose (to make ipython session available).
4 Needs to be run by nose (to make ipython session available).
5 """
5 """
6
6
7 import io
7 import io
8 import os
8 import os
9 import re
9 import re
10 import sys
10 import sys
11 import warnings
11 import warnings
12 from textwrap import dedent
12 from textwrap import dedent
13 from unittest import TestCase
13 from unittest import TestCase
14 from unittest import mock
14 from unittest import mock
15 from importlib import invalidate_caches
15 from importlib import invalidate_caches
16 from io import StringIO
16 from io import StringIO
17 from pathlib import Path
17 from pathlib import Path
18
18
19 import nose.tools as nt
19 import nose.tools as nt
20
20
21 import shlex
21 import shlex
22
22
23 from IPython import get_ipython
23 from IPython import get_ipython
24 from IPython.core import magic
24 from IPython.core import magic
25 from IPython.core.error import UsageError
25 from IPython.core.error import UsageError
26 from IPython.core.magic import (Magics, magics_class, line_magic,
26 from IPython.core.magic import (Magics, magics_class, line_magic,
27 cell_magic,
27 cell_magic,
28 register_line_magic, register_cell_magic)
28 register_line_magic, register_cell_magic)
29 from IPython.core.magics import execution, script, code, logging, osm
29 from IPython.core.magics import execution, script, code, logging, osm
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing import tools as tt
31 from IPython.testing import tools as tt
32 from IPython.utils.io import capture_output
32 from IPython.utils.io import capture_output
33 from IPython.utils.tempdir import (TemporaryDirectory,
33 from IPython.utils.tempdir import (TemporaryDirectory,
34 TemporaryWorkingDirectory)
34 TemporaryWorkingDirectory)
35 from IPython.utils.process import find_cmd
35 from IPython.utils.process import find_cmd
36 from .test_debugger import PdbTestInput
36 from .test_debugger import PdbTestInput
37
37
38
38
39 @magic.magics_class
39 @magic.magics_class
40 class DummyMagics(magic.Magics): pass
40 class DummyMagics(magic.Magics): pass
41
41
42 def test_extract_code_ranges():
42 def test_extract_code_ranges():
43 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
43 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
44 expected = [(0, 1),
44 expected = [(0, 1),
45 (2, 3),
45 (2, 3),
46 (4, 6),
46 (4, 6),
47 (6, 9),
47 (6, 9),
48 (9, 14),
48 (9, 14),
49 (16, None),
49 (16, None),
50 (None, 9),
50 (None, 9),
51 (9, None),
51 (9, None),
52 (None, 13),
52 (None, 13),
53 (None, None)]
53 (None, None)]
54 actual = list(code.extract_code_ranges(instr))
54 actual = list(code.extract_code_ranges(instr))
55 nt.assert_equal(actual, expected)
55 nt.assert_equal(actual, expected)
56
56
57 def test_extract_symbols():
57 def test_extract_symbols():
58 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
58 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
59 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
59 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
60 expected = [([], ['a']),
60 expected = [([], ['a']),
61 (["def b():\n return 42\n"], []),
61 (["def b():\n return 42\n"], []),
62 (["class A: pass\n"], []),
62 (["class A: pass\n"], []),
63 (["class A: pass\n", "def b():\n return 42\n"], []),
63 (["class A: pass\n", "def b():\n return 42\n"], []),
64 (["class A: pass\n"], ['a']),
64 (["class A: pass\n"], ['a']),
65 ([], ['z'])]
65 ([], ['z'])]
66 for symbols, exp in zip(symbols_args, expected):
66 for symbols, exp in zip(symbols_args, expected):
67 nt.assert_equal(code.extract_symbols(source, symbols), exp)
67 nt.assert_equal(code.extract_symbols(source, symbols), exp)
68
68
69
69
70 def test_extract_symbols_raises_exception_with_non_python_code():
70 def test_extract_symbols_raises_exception_with_non_python_code():
71 source = ("=begin A Ruby program :)=end\n"
71 source = ("=begin A Ruby program :)=end\n"
72 "def hello\n"
72 "def hello\n"
73 "puts 'Hello world'\n"
73 "puts 'Hello world'\n"
74 "end")
74 "end")
75 with nt.assert_raises(SyntaxError):
75 with nt.assert_raises(SyntaxError):
76 code.extract_symbols(source, "hello")
76 code.extract_symbols(source, "hello")
77
77
78
78
79 def test_magic_not_found():
79 def test_magic_not_found():
80 # magic not found raises UsageError
80 # magic not found raises UsageError
81 with nt.assert_raises(UsageError):
81 with nt.assert_raises(UsageError):
82 _ip.magic('doesntexist')
82 _ip.magic('doesntexist')
83
83
84 # ensure result isn't success when a magic isn't found
84 # ensure result isn't success when a magic isn't found
85 result = _ip.run_cell('%doesntexist')
85 result = _ip.run_cell('%doesntexist')
86 assert isinstance(result.error_in_exec, UsageError)
86 assert isinstance(result.error_in_exec, UsageError)
87
87
88
88
89 def test_cell_magic_not_found():
89 def test_cell_magic_not_found():
90 # magic not found raises UsageError
90 # magic not found raises UsageError
91 with nt.assert_raises(UsageError):
91 with nt.assert_raises(UsageError):
92 _ip.run_cell_magic('doesntexist', 'line', 'cell')
92 _ip.run_cell_magic('doesntexist', 'line', 'cell')
93
93
94 # ensure result isn't success when a magic isn't found
94 # ensure result isn't success when a magic isn't found
95 result = _ip.run_cell('%%doesntexist')
95 result = _ip.run_cell('%%doesntexist')
96 assert isinstance(result.error_in_exec, UsageError)
96 assert isinstance(result.error_in_exec, UsageError)
97
97
98
98
99 def test_magic_error_status():
99 def test_magic_error_status():
100 def fail(shell):
100 def fail(shell):
101 1/0
101 1/0
102 _ip.register_magic_function(fail)
102 _ip.register_magic_function(fail)
103 result = _ip.run_cell('%fail')
103 result = _ip.run_cell('%fail')
104 assert isinstance(result.error_in_exec, ZeroDivisionError)
104 assert isinstance(result.error_in_exec, ZeroDivisionError)
105
105
106
106
107 def test_config():
107 def test_config():
108 """ test that config magic does not raise
108 """ test that config magic does not raise
109 can happen if Configurable init is moved too early into
109 can happen if Configurable init is moved too early into
110 Magics.__init__ as then a Config object will be registered as a
110 Magics.__init__ as then a Config object will be registered as a
111 magic.
111 magic.
112 """
112 """
113 ## should not raise.
113 ## should not raise.
114 _ip.magic('config')
114 _ip.magic('config')
115
115
116 def test_config_available_configs():
116 def test_config_available_configs():
117 """ test that config magic prints available configs in unique and
117 """ test that config magic prints available configs in unique and
118 sorted order. """
118 sorted order. """
119 with capture_output() as captured:
119 with capture_output() as captured:
120 _ip.magic('config')
120 _ip.magic('config')
121
121
122 stdout = captured.stdout
122 stdout = captured.stdout
123 config_classes = stdout.strip().split('\n')[1:]
123 config_classes = stdout.strip().split('\n')[1:]
124 nt.assert_list_equal(config_classes, sorted(set(config_classes)))
124 nt.assert_list_equal(config_classes, sorted(set(config_classes)))
125
125
126 def test_config_print_class():
126 def test_config_print_class():
127 """ test that config with a classname prints the class's options. """
127 """ test that config with a classname prints the class's options. """
128 with capture_output() as captured:
128 with capture_output() as captured:
129 _ip.magic('config TerminalInteractiveShell')
129 _ip.magic('config TerminalInteractiveShell')
130
130
131 stdout = captured.stdout
131 stdout = captured.stdout
132 if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]):
132 if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]):
133 print(stdout)
133 print(stdout)
134 raise AssertionError("1st line of stdout not like "
134 raise AssertionError("1st line of stdout not like "
135 "'TerminalInteractiveShell.* options'")
135 "'TerminalInteractiveShell.* options'")
136
136
137 def test_rehashx():
137 def test_rehashx():
138 # clear up everything
138 # clear up everything
139 _ip.alias_manager.clear_aliases()
139 _ip.alias_manager.clear_aliases()
140 del _ip.db['syscmdlist']
140 del _ip.db['syscmdlist']
141
141
142 _ip.magic('rehashx')
142 _ip.magic('rehashx')
143 # Practically ALL ipython development systems will have more than 10 aliases
143 # Practically ALL ipython development systems will have more than 10 aliases
144
144
145 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
145 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
146 for name, cmd in _ip.alias_manager.aliases:
146 for name, cmd in _ip.alias_manager.aliases:
147 # we must strip dots from alias names
147 # we must strip dots from alias names
148 nt.assert_not_in('.', name)
148 nt.assert_not_in('.', name)
149
149
150 # rehashx must fill up syscmdlist
150 # rehashx must fill up syscmdlist
151 scoms = _ip.db['syscmdlist']
151 scoms = _ip.db['syscmdlist']
152 nt.assert_true(len(scoms) > 10)
152 nt.assert_true(len(scoms) > 10)
153
153
154
154
155
155
156 def test_magic_parse_options():
156 def test_magic_parse_options():
157 """Test that we don't mangle paths when parsing magic options."""
157 """Test that we don't mangle paths when parsing magic options."""
158 ip = get_ipython()
158 ip = get_ipython()
159 path = 'c:\\x'
159 path = 'c:\\x'
160 m = DummyMagics(ip)
160 m = DummyMagics(ip)
161 opts = m.parse_options('-f %s' % path,'f:')[0]
161 opts = m.parse_options('-f %s' % path,'f:')[0]
162 # argv splitting is os-dependent
162 # argv splitting is os-dependent
163 if os.name == 'posix':
163 if os.name == 'posix':
164 expected = 'c:x'
164 expected = 'c:x'
165 else:
165 else:
166 expected = path
166 expected = path
167 nt.assert_equal(opts['f'], expected)
167 nt.assert_equal(opts['f'], expected)
168
168
169 def test_magic_parse_long_options():
169 def test_magic_parse_long_options():
170 """Magic.parse_options can handle --foo=bar long options"""
170 """Magic.parse_options can handle --foo=bar long options"""
171 ip = get_ipython()
171 ip = get_ipython()
172 m = DummyMagics(ip)
172 m = DummyMagics(ip)
173 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
173 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
174 nt.assert_in('foo', opts)
174 nt.assert_in('foo', opts)
175 nt.assert_in('bar', opts)
175 nt.assert_in('bar', opts)
176 nt.assert_equal(opts['bar'], "bubble")
176 nt.assert_equal(opts['bar'], "bubble")
177
177
178
178
179 def doctest_hist_f():
179 def doctest_hist_f():
180 """Test %hist -f with temporary filename.
180 """Test %hist -f with temporary filename.
181
181
182 In [9]: import tempfile
182 In [9]: import tempfile
183
183
184 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
184 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
185
185
186 In [11]: %hist -nl -f $tfile 3
186 In [11]: %hist -nl -f $tfile 3
187
187
188 In [13]: import os; os.unlink(tfile)
188 In [13]: import os; os.unlink(tfile)
189 """
189 """
190
190
191
191
192 def doctest_hist_op():
192 def doctest_hist_op():
193 """Test %hist -op
193 """Test %hist -op
194
194
195 In [1]: class b(float):
195 In [1]: class b(float):
196 ...: pass
196 ...: pass
197 ...:
197 ...:
198
198
199 In [2]: class s(object):
199 In [2]: class s(object):
200 ...: def __str__(self):
200 ...: def __str__(self):
201 ...: return 's'
201 ...: return 's'
202 ...:
202 ...:
203
203
204 In [3]:
204 In [3]:
205
205
206 In [4]: class r(b):
206 In [4]: class r(b):
207 ...: def __repr__(self):
207 ...: def __repr__(self):
208 ...: return 'r'
208 ...: return 'r'
209 ...:
209 ...:
210
210
211 In [5]: class sr(s,r): pass
211 In [5]: class sr(s,r): pass
212 ...:
212 ...:
213
213
214 In [6]:
214 In [6]:
215
215
216 In [7]: bb=b()
216 In [7]: bb=b()
217
217
218 In [8]: ss=s()
218 In [8]: ss=s()
219
219
220 In [9]: rr=r()
220 In [9]: rr=r()
221
221
222 In [10]: ssrr=sr()
222 In [10]: ssrr=sr()
223
223
224 In [11]: 4.5
224 In [11]: 4.5
225 Out[11]: 4.5
225 Out[11]: 4.5
226
226
227 In [12]: str(ss)
227 In [12]: str(ss)
228 Out[12]: 's'
228 Out[12]: 's'
229
229
230 In [13]:
230 In [13]:
231
231
232 In [14]: %hist -op
232 In [14]: %hist -op
233 >>> class b:
233 >>> class b:
234 ... pass
234 ... pass
235 ...
235 ...
236 >>> class s(b):
236 >>> class s(b):
237 ... def __str__(self):
237 ... def __str__(self):
238 ... return 's'
238 ... return 's'
239 ...
239 ...
240 >>>
240 >>>
241 >>> class r(b):
241 >>> class r(b):
242 ... def __repr__(self):
242 ... def __repr__(self):
243 ... return 'r'
243 ... return 'r'
244 ...
244 ...
245 >>> class sr(s,r): pass
245 >>> class sr(s,r): pass
246 >>>
246 >>>
247 >>> bb=b()
247 >>> bb=b()
248 >>> ss=s()
248 >>> ss=s()
249 >>> rr=r()
249 >>> rr=r()
250 >>> ssrr=sr()
250 >>> ssrr=sr()
251 >>> 4.5
251 >>> 4.5
252 4.5
252 4.5
253 >>> str(ss)
253 >>> str(ss)
254 's'
254 's'
255 >>>
255 >>>
256 """
256 """
257
257
258 def test_hist_pof():
258 def test_hist_pof():
259 ip = get_ipython()
259 ip = get_ipython()
260 ip.run_cell(u"1+2", store_history=True)
260 ip.run_cell(u"1+2", store_history=True)
261 #raise Exception(ip.history_manager.session_number)
261 #raise Exception(ip.history_manager.session_number)
262 #raise Exception(list(ip.history_manager._get_range_session()))
262 #raise Exception(list(ip.history_manager._get_range_session()))
263 with TemporaryDirectory() as td:
263 with TemporaryDirectory() as td:
264 tf = os.path.join(td, 'hist.py')
264 tf = os.path.join(td, 'hist.py')
265 ip.run_line_magic('history', '-pof %s' % tf)
265 ip.run_line_magic('history', '-pof %s' % tf)
266 assert os.path.isfile(tf)
266 assert os.path.isfile(tf)
267
267
268
268
269 def test_macro():
269 def test_macro():
270 ip = get_ipython()
270 ip = get_ipython()
271 ip.history_manager.reset() # Clear any existing history.
271 ip.history_manager.reset() # Clear any existing history.
272 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
272 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
273 for i, cmd in enumerate(cmds, start=1):
273 for i, cmd in enumerate(cmds, start=1):
274 ip.history_manager.store_inputs(i, cmd)
274 ip.history_manager.store_inputs(i, cmd)
275 ip.magic("macro test 1-3")
275 ip.magic("macro test 1-3")
276 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
276 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
277
277
278 # List macros
278 # List macros
279 nt.assert_in("test", ip.magic("macro"))
279 nt.assert_in("test", ip.magic("macro"))
280
280
281
281
282 def test_macro_run():
282 def test_macro_run():
283 """Test that we can run a multi-line macro successfully."""
283 """Test that we can run a multi-line macro successfully."""
284 ip = get_ipython()
284 ip = get_ipython()
285 ip.history_manager.reset()
285 ip.history_manager.reset()
286 cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"]
286 cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"]
287 for cmd in cmds:
287 for cmd in cmds:
288 ip.run_cell(cmd, store_history=True)
288 ip.run_cell(cmd, store_history=True)
289 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint(a)\n")
289 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint(a)\n")
290 with tt.AssertPrints("12"):
290 with tt.AssertPrints("12"):
291 ip.run_cell("test")
291 ip.run_cell("test")
292 with tt.AssertPrints("13"):
292 with tt.AssertPrints("13"):
293 ip.run_cell("test")
293 ip.run_cell("test")
294
294
295
295
296 def test_magic_magic():
296 def test_magic_magic():
297 """Test %magic"""
297 """Test %magic"""
298 ip = get_ipython()
298 ip = get_ipython()
299 with capture_output() as captured:
299 with capture_output() as captured:
300 ip.magic("magic")
300 ip.magic("magic")
301
301
302 stdout = captured.stdout
302 stdout = captured.stdout
303 nt.assert_in('%magic', stdout)
303 nt.assert_in('%magic', stdout)
304 nt.assert_in('IPython', stdout)
304 nt.assert_in('IPython', stdout)
305 nt.assert_in('Available', stdout)
305 nt.assert_in('Available', stdout)
306
306
307
307
308 @dec.skipif_not_numpy
308 @dec.skipif_not_numpy
309 def test_numpy_reset_array_undec():
309 def test_numpy_reset_array_undec():
310 "Test '%reset array' functionality"
310 "Test '%reset array' functionality"
311 _ip.ex('import numpy as np')
311 _ip.ex('import numpy as np')
312 _ip.ex('a = np.empty(2)')
312 _ip.ex('a = np.empty(2)')
313 nt.assert_in('a', _ip.user_ns)
313 nt.assert_in('a', _ip.user_ns)
314 _ip.magic('reset -f array')
314 _ip.magic('reset -f array')
315 nt.assert_not_in('a', _ip.user_ns)
315 nt.assert_not_in('a', _ip.user_ns)
316
316
317 def test_reset_out():
317 def test_reset_out():
318 "Test '%reset out' magic"
318 "Test '%reset out' magic"
319 _ip.run_cell("parrot = 'dead'", store_history=True)
319 _ip.run_cell("parrot = 'dead'", store_history=True)
320 # test '%reset -f out', make an Out prompt
320 # test '%reset -f out', make an Out prompt
321 _ip.run_cell("parrot", store_history=True)
321 _ip.run_cell("parrot", store_history=True)
322 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
322 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
323 _ip.magic('reset -f out')
323 _ip.magic('reset -f out')
324 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
324 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
325 nt.assert_equal(len(_ip.user_ns['Out']), 0)
325 nt.assert_equal(len(_ip.user_ns['Out']), 0)
326
326
327 def test_reset_in():
327 def test_reset_in():
328 "Test '%reset in' magic"
328 "Test '%reset in' magic"
329 # test '%reset -f in'
329 # test '%reset -f in'
330 _ip.run_cell("parrot", store_history=True)
330 _ip.run_cell("parrot", store_history=True)
331 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
331 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
332 _ip.magic('%reset -f in')
332 _ip.magic('%reset -f in')
333 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
333 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
334 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
334 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
335
335
336 def test_reset_dhist():
336 def test_reset_dhist():
337 "Test '%reset dhist' magic"
337 "Test '%reset dhist' magic"
338 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
338 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
339 _ip.magic('cd ' + os.path.dirname(nt.__file__))
339 _ip.magic('cd ' + os.path.dirname(nt.__file__))
340 _ip.magic('cd -')
340 _ip.magic('cd -')
341 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
341 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
342 _ip.magic('reset -f dhist')
342 _ip.magic('reset -f dhist')
343 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
343 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
344 _ip.run_cell("_dh = [d for d in tmp]") #restore
344 _ip.run_cell("_dh = [d for d in tmp]") #restore
345
345
346 def test_reset_in_length():
346 def test_reset_in_length():
347 "Test that '%reset in' preserves In[] length"
347 "Test that '%reset in' preserves In[] length"
348 _ip.run_cell("print 'foo'")
348 _ip.run_cell("print 'foo'")
349 _ip.run_cell("reset -f in")
349 _ip.run_cell("reset -f in")
350 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
350 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
351
351
352 class TestResetErrors(TestCase):
352 class TestResetErrors(TestCase):
353
353
354 def test_reset_redefine(self):
354 def test_reset_redefine(self):
355
355
356 @magics_class
356 @magics_class
357 class KernelMagics(Magics):
357 class KernelMagics(Magics):
358 @line_magic
358 @line_magic
359 def less(self, shell): pass
359 def less(self, shell): pass
360
360
361 _ip.register_magics(KernelMagics)
361 _ip.register_magics(KernelMagics)
362
362
363 with self.assertLogs() as cm:
363 with self.assertLogs() as cm:
364 # hack, we want to just capture logs, but assertLogs fails if not
364 # hack, we want to just capture logs, but assertLogs fails if not
365 # logs get produce.
365 # logs get produce.
366 # so log one things we ignore.
366 # so log one things we ignore.
367 import logging as log_mod
367 import logging as log_mod
368 log = log_mod.getLogger()
368 log = log_mod.getLogger()
369 log.info('Nothing')
369 log.info('Nothing')
370 # end hack.
370 # end hack.
371 _ip.run_cell("reset -f")
371 _ip.run_cell("reset -f")
372
372
373 assert len(cm.output) == 1
373 assert len(cm.output) == 1
374 for out in cm.output:
374 for out in cm.output:
375 assert "Invalid alias" not in out
375 assert "Invalid alias" not in out
376
376
377 def test_tb_syntaxerror():
377 def test_tb_syntaxerror():
378 """test %tb after a SyntaxError"""
378 """test %tb after a SyntaxError"""
379 ip = get_ipython()
379 ip = get_ipython()
380 ip.run_cell("for")
380 ip.run_cell("for")
381
381
382 # trap and validate stdout
382 # trap and validate stdout
383 save_stdout = sys.stdout
383 save_stdout = sys.stdout
384 try:
384 try:
385 sys.stdout = StringIO()
385 sys.stdout = StringIO()
386 ip.run_cell("%tb")
386 ip.run_cell("%tb")
387 out = sys.stdout.getvalue()
387 out = sys.stdout.getvalue()
388 finally:
388 finally:
389 sys.stdout = save_stdout
389 sys.stdout = save_stdout
390 # trim output, and only check the last line
390 # trim output, and only check the last line
391 last_line = out.rstrip().splitlines()[-1].strip()
391 last_line = out.rstrip().splitlines()[-1].strip()
392 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
392 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
393
393
394
394
395 def test_time():
395 def test_time():
396 ip = get_ipython()
396 ip = get_ipython()
397
397
398 with tt.AssertPrints("Wall time: "):
398 with tt.AssertPrints("Wall time: "):
399 ip.run_cell("%time None")
399 ip.run_cell("%time None")
400
400
401 ip.run_cell("def f(kmjy):\n"
401 ip.run_cell("def f(kmjy):\n"
402 " %time print (2*kmjy)")
402 " %time print (2*kmjy)")
403
403
404 with tt.AssertPrints("Wall time: "):
404 with tt.AssertPrints("Wall time: "):
405 with tt.AssertPrints("hihi", suppress=False):
405 with tt.AssertPrints("hihi", suppress=False):
406 ip.run_cell("f('hi')")
406 ip.run_cell("f('hi')")
407
407
408 def test_time_last_not_expression():
408 def test_time_last_not_expression():
409 ip.run_cell("%%time\n"
409 ip.run_cell("%%time\n"
410 "var_1 = 1\n"
410 "var_1 = 1\n"
411 "var_2 = 2\n")
411 "var_2 = 2\n")
412 assert ip.user_ns['var_1'] == 1
412 assert ip.user_ns['var_1'] == 1
413 del ip.user_ns['var_1']
413 del ip.user_ns['var_1']
414 assert ip.user_ns['var_2'] == 2
414 assert ip.user_ns['var_2'] == 2
415 del ip.user_ns['var_2']
415 del ip.user_ns['var_2']
416
416
417
417
418 @dec.skip_win32
418 @dec.skip_win32
419 def test_time2():
419 def test_time2():
420 ip = get_ipython()
420 ip = get_ipython()
421
421
422 with tt.AssertPrints("CPU times: user "):
422 with tt.AssertPrints("CPU times: user "):
423 ip.run_cell("%time None")
423 ip.run_cell("%time None")
424
424
425 def test_time3():
425 def test_time3():
426 """Erroneous magic function calls, issue gh-3334"""
426 """Erroneous magic function calls, issue gh-3334"""
427 ip = get_ipython()
427 ip = get_ipython()
428 ip.user_ns.pop('run', None)
428 ip.user_ns.pop('run', None)
429
429
430 with tt.AssertNotPrints("not found", channel='stderr'):
430 with tt.AssertNotPrints("not found", channel='stderr'):
431 ip.run_cell("%%time\n"
431 ip.run_cell("%%time\n"
432 "run = 0\n"
432 "run = 0\n"
433 "run += 1")
433 "run += 1")
434
434
435 def test_multiline_time():
435 def test_multiline_time():
436 """Make sure last statement from time return a value."""
436 """Make sure last statement from time return a value."""
437 ip = get_ipython()
437 ip = get_ipython()
438 ip.user_ns.pop('run', None)
438 ip.user_ns.pop('run', None)
439
439
440 ip.run_cell(dedent("""\
440 ip.run_cell(dedent("""\
441 %%time
441 %%time
442 a = "ho"
442 a = "ho"
443 b = "hey"
443 b = "hey"
444 a+b
444 a+b
445 """))
445 """))
446 nt.assert_equal(ip.user_ns_hidden['_'], 'hohey')
446 nt.assert_equal(ip.user_ns_hidden['_'], 'hohey')
447
447
448 def test_time_local_ns():
448 def test_time_local_ns():
449 """
449 """
450 Test that local_ns is actually global_ns when running a cell magic
450 Test that local_ns is actually global_ns when running a cell magic
451 """
451 """
452 ip = get_ipython()
452 ip = get_ipython()
453 ip.run_cell("%%time\n"
453 ip.run_cell("%%time\n"
454 "myvar = 1")
454 "myvar = 1")
455 nt.assert_equal(ip.user_ns['myvar'], 1)
455 nt.assert_equal(ip.user_ns['myvar'], 1)
456 del ip.user_ns['myvar']
456 del ip.user_ns['myvar']
457
457
458 def test_doctest_mode():
458 def test_doctest_mode():
459 "Toggle doctest_mode twice, it should be a no-op and run without error"
459 "Toggle doctest_mode twice, it should be a no-op and run without error"
460 _ip.magic('doctest_mode')
460 _ip.magic('doctest_mode')
461 _ip.magic('doctest_mode')
461 _ip.magic('doctest_mode')
462
462
463
463
464 def test_parse_options():
464 def test_parse_options():
465 """Tests for basic options parsing in magics."""
465 """Tests for basic options parsing in magics."""
466 # These are only the most minimal of tests, more should be added later. At
466 # These are only the most minimal of tests, more should be added later. At
467 # the very least we check that basic text/unicode calls work OK.
467 # the very least we check that basic text/unicode calls work OK.
468 m = DummyMagics(_ip)
468 m = DummyMagics(_ip)
469 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
469 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
470 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
470 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
471
471
472
472
473 def test_parse_options_preserve_non_option_string():
473 def test_parse_options_preserve_non_option_string():
474 """Test to assert preservation of non-option part of magic-block, while parsing magic options."""
474 """Test to assert preservation of non-option part of magic-block, while parsing magic options."""
475 m = DummyMagics(_ip)
475 m = DummyMagics(_ip)
476 opts, stmt = m.parse_options(' -n1 -r 13 _ = 314 + foo', 'n:r:', preserve_non_opts= True)
476 opts, stmt = m.parse_options(
477 nt.assert_equal(opts, {'n': '1', 'r': '13'})
477 " -n1 -r 13 _ = 314 + foo", "n:r:", preserve_non_opts=True
478 nt.assert_equal(stmt, '_ = 314 + foo')
478 )
479 nt.assert_equal(opts, {"n": "1", "r": "13"})
480 nt.assert_equal(stmt, "_ = 314 + foo")
479
481
480
482
481 def test_run_magic_preserve_code_block():
483 def test_run_magic_preserve_code_block():
482 """Test to assert preservation of non-option part of magic-block, while running magic."""
484 """Test to assert preservation of non-option part of magic-block, while running magic."""
483 _ip.user_ns['spaces'] = []
485 _ip.user_ns["spaces"] = []
484 _ip.magic("timeit -n1 -r1 spaces.append([s.count(' ') for s in ['document']])")
486 _ip.magic("timeit -n1 -r1 spaces.append([s.count(' ') for s in ['document']])")
485 assert _ip.user_ns['spaces'] == [[0]]
487 assert _ip.user_ns["spaces"] == [[0]]
486
488
487
489
488 def test_dirops():
490 def test_dirops():
489 """Test various directory handling operations."""
491 """Test various directory handling operations."""
490 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
492 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
491 curpath = os.getcwd
493 curpath = os.getcwd
492 startdir = os.getcwd()
494 startdir = os.getcwd()
493 ipdir = os.path.realpath(_ip.ipython_dir)
495 ipdir = os.path.realpath(_ip.ipython_dir)
494 try:
496 try:
495 _ip.magic('cd "%s"' % ipdir)
497 _ip.magic('cd "%s"' % ipdir)
496 nt.assert_equal(curpath(), ipdir)
498 nt.assert_equal(curpath(), ipdir)
497 _ip.magic('cd -')
499 _ip.magic('cd -')
498 nt.assert_equal(curpath(), startdir)
500 nt.assert_equal(curpath(), startdir)
499 _ip.magic('pushd "%s"' % ipdir)
501 _ip.magic('pushd "%s"' % ipdir)
500 nt.assert_equal(curpath(), ipdir)
502 nt.assert_equal(curpath(), ipdir)
501 _ip.magic('popd')
503 _ip.magic('popd')
502 nt.assert_equal(curpath(), startdir)
504 nt.assert_equal(curpath(), startdir)
503 finally:
505 finally:
504 os.chdir(startdir)
506 os.chdir(startdir)
505
507
506
508
507 def test_cd_force_quiet():
509 def test_cd_force_quiet():
508 """Test OSMagics.cd_force_quiet option"""
510 """Test OSMagics.cd_force_quiet option"""
509 _ip.config.OSMagics.cd_force_quiet = True
511 _ip.config.OSMagics.cd_force_quiet = True
510 osmagics = osm.OSMagics(shell=_ip)
512 osmagics = osm.OSMagics(shell=_ip)
511
513
512 startdir = os.getcwd()
514 startdir = os.getcwd()
513 ipdir = os.path.realpath(_ip.ipython_dir)
515 ipdir = os.path.realpath(_ip.ipython_dir)
514
516
515 try:
517 try:
516 with tt.AssertNotPrints(ipdir):
518 with tt.AssertNotPrints(ipdir):
517 osmagics.cd('"%s"' % ipdir)
519 osmagics.cd('"%s"' % ipdir)
518 with tt.AssertNotPrints(startdir):
520 with tt.AssertNotPrints(startdir):
519 osmagics.cd('-')
521 osmagics.cd('-')
520 finally:
522 finally:
521 os.chdir(startdir)
523 os.chdir(startdir)
522
524
523
525
524 def test_xmode():
526 def test_xmode():
525 # Calling xmode three times should be a no-op
527 # Calling xmode three times should be a no-op
526 xmode = _ip.InteractiveTB.mode
528 xmode = _ip.InteractiveTB.mode
527 for i in range(4):
529 for i in range(4):
528 _ip.magic("xmode")
530 _ip.magic("xmode")
529 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
531 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
530
532
531 def test_reset_hard():
533 def test_reset_hard():
532 monitor = []
534 monitor = []
533 class A(object):
535 class A(object):
534 def __del__(self):
536 def __del__(self):
535 monitor.append(1)
537 monitor.append(1)
536 def __repr__(self):
538 def __repr__(self):
537 return "<A instance>"
539 return "<A instance>"
538
540
539 _ip.user_ns["a"] = A()
541 _ip.user_ns["a"] = A()
540 _ip.run_cell("a")
542 _ip.run_cell("a")
541
543
542 nt.assert_equal(monitor, [])
544 nt.assert_equal(monitor, [])
543 _ip.magic("reset -f")
545 _ip.magic("reset -f")
544 nt.assert_equal(monitor, [1])
546 nt.assert_equal(monitor, [1])
545
547
546 class TestXdel(tt.TempFileMixin):
548 class TestXdel(tt.TempFileMixin):
547 def test_xdel(self):
549 def test_xdel(self):
548 """Test that references from %run are cleared by xdel."""
550 """Test that references from %run are cleared by xdel."""
549 src = ("class A(object):\n"
551 src = ("class A(object):\n"
550 " monitor = []\n"
552 " monitor = []\n"
551 " def __del__(self):\n"
553 " def __del__(self):\n"
552 " self.monitor.append(1)\n"
554 " self.monitor.append(1)\n"
553 "a = A()\n")
555 "a = A()\n")
554 self.mktmp(src)
556 self.mktmp(src)
555 # %run creates some hidden references...
557 # %run creates some hidden references...
556 _ip.magic("run %s" % self.fname)
558 _ip.magic("run %s" % self.fname)
557 # ... as does the displayhook.
559 # ... as does the displayhook.
558 _ip.run_cell("a")
560 _ip.run_cell("a")
559
561
560 monitor = _ip.user_ns["A"].monitor
562 monitor = _ip.user_ns["A"].monitor
561 nt.assert_equal(monitor, [])
563 nt.assert_equal(monitor, [])
562
564
563 _ip.magic("xdel a")
565 _ip.magic("xdel a")
564
566
565 # Check that a's __del__ method has been called.
567 # Check that a's __del__ method has been called.
566 nt.assert_equal(monitor, [1])
568 nt.assert_equal(monitor, [1])
567
569
568 def doctest_who():
570 def doctest_who():
569 """doctest for %who
571 """doctest for %who
570
572
571 In [1]: %reset -f
573 In [1]: %reset -f
572
574
573 In [2]: alpha = 123
575 In [2]: alpha = 123
574
576
575 In [3]: beta = 'beta'
577 In [3]: beta = 'beta'
576
578
577 In [4]: %who int
579 In [4]: %who int
578 alpha
580 alpha
579
581
580 In [5]: %who str
582 In [5]: %who str
581 beta
583 beta
582
584
583 In [6]: %whos
585 In [6]: %whos
584 Variable Type Data/Info
586 Variable Type Data/Info
585 ----------------------------
587 ----------------------------
586 alpha int 123
588 alpha int 123
587 beta str beta
589 beta str beta
588
590
589 In [7]: %who_ls
591 In [7]: %who_ls
590 Out[7]: ['alpha', 'beta']
592 Out[7]: ['alpha', 'beta']
591 """
593 """
592
594
593 def test_whos():
595 def test_whos():
594 """Check that whos is protected against objects where repr() fails."""
596 """Check that whos is protected against objects where repr() fails."""
595 class A(object):
597 class A(object):
596 def __repr__(self):
598 def __repr__(self):
597 raise Exception()
599 raise Exception()
598 _ip.user_ns['a'] = A()
600 _ip.user_ns['a'] = A()
599 _ip.magic("whos")
601 _ip.magic("whos")
600
602
601 def doctest_precision():
603 def doctest_precision():
602 """doctest for %precision
604 """doctest for %precision
603
605
604 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
606 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
605
607
606 In [2]: %precision 5
608 In [2]: %precision 5
607 Out[2]: '%.5f'
609 Out[2]: '%.5f'
608
610
609 In [3]: f.float_format
611 In [3]: f.float_format
610 Out[3]: '%.5f'
612 Out[3]: '%.5f'
611
613
612 In [4]: %precision %e
614 In [4]: %precision %e
613 Out[4]: '%e'
615 Out[4]: '%e'
614
616
615 In [5]: f(3.1415927)
617 In [5]: f(3.1415927)
616 Out[5]: '3.141593e+00'
618 Out[5]: '3.141593e+00'
617 """
619 """
618
620
619 def test_debug_magic():
621 def test_debug_magic():
620 """Test debugging a small code with %debug
622 """Test debugging a small code with %debug
621
623
622 In [1]: with PdbTestInput(['c']):
624 In [1]: with PdbTestInput(['c']):
623 ...: %debug print("a b") #doctest: +ELLIPSIS
625 ...: %debug print("a b") #doctest: +ELLIPSIS
624 ...:
626 ...:
625 ...
627 ...
626 ipdb> c
628 ipdb> c
627 a b
629 a b
628 In [2]:
630 In [2]:
629 """
631 """
630
632
631 def test_psearch():
633 def test_psearch():
632 with tt.AssertPrints("dict.fromkeys"):
634 with tt.AssertPrints("dict.fromkeys"):
633 _ip.run_cell("dict.fr*?")
635 _ip.run_cell("dict.fr*?")
634 with tt.AssertPrints("Ο€.is_integer"):
636 with tt.AssertPrints("Ο€.is_integer"):
635 _ip.run_cell("Ο€ = 3.14;\nΟ€.is_integ*?")
637 _ip.run_cell("Ο€ = 3.14;\nΟ€.is_integ*?")
636
638
637 def test_timeit_shlex():
639 def test_timeit_shlex():
638 """test shlex issues with timeit (#1109)"""
640 """test shlex issues with timeit (#1109)"""
639 _ip.ex("def f(*a,**kw): pass")
641 _ip.ex("def f(*a,**kw): pass")
640 _ip.magic('timeit -n1 "this is a bug".count(" ")')
642 _ip.magic('timeit -n1 "this is a bug".count(" ")')
641 _ip.magic('timeit -r1 -n1 f(" ", 1)')
643 _ip.magic('timeit -r1 -n1 f(" ", 1)')
642 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
644 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
643 _ip.magic('timeit -r1 -n1 ("a " + "b")')
645 _ip.magic('timeit -r1 -n1 ("a " + "b")')
644 _ip.magic('timeit -r1 -n1 f("a " + "b")')
646 _ip.magic('timeit -r1 -n1 f("a " + "b")')
645 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
647 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
646
648
647
649
648 def test_timeit_special_syntax():
650 def test_timeit_special_syntax():
649 "Test %%timeit with IPython special syntax"
651 "Test %%timeit with IPython special syntax"
650 @register_line_magic
652 @register_line_magic
651 def lmagic(line):
653 def lmagic(line):
652 ip = get_ipython()
654 ip = get_ipython()
653 ip.user_ns['lmagic_out'] = line
655 ip.user_ns['lmagic_out'] = line
654
656
655 # line mode test
657 # line mode test
656 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
658 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
657 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
659 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
658 # cell mode test
660 # cell mode test
659 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
661 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
660 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
662 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
661
663
662 def test_timeit_return():
664 def test_timeit_return():
663 """
665 """
664 test whether timeit -o return object
666 test whether timeit -o return object
665 """
667 """
666
668
667 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
669 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
668 assert(res is not None)
670 assert(res is not None)
669
671
670 def test_timeit_quiet():
672 def test_timeit_quiet():
671 """
673 """
672 test quiet option of timeit magic
674 test quiet option of timeit magic
673 """
675 """
674 with tt.AssertNotPrints("loops"):
676 with tt.AssertNotPrints("loops"):
675 _ip.run_cell("%timeit -n1 -r1 -q 1")
677 _ip.run_cell("%timeit -n1 -r1 -q 1")
676
678
677 def test_timeit_return_quiet():
679 def test_timeit_return_quiet():
678 with tt.AssertNotPrints("loops"):
680 with tt.AssertNotPrints("loops"):
679 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
681 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
680 assert (res is not None)
682 assert (res is not None)
681
683
682 def test_timeit_invalid_return():
684 def test_timeit_invalid_return():
683 with nt.assert_raises_regex(SyntaxError, "outside function"):
685 with nt.assert_raises_regex(SyntaxError, "outside function"):
684 _ip.run_line_magic('timeit', 'return')
686 _ip.run_line_magic('timeit', 'return')
685
687
686 @dec.skipif(execution.profile is None)
688 @dec.skipif(execution.profile is None)
687 def test_prun_special_syntax():
689 def test_prun_special_syntax():
688 "Test %%prun with IPython special syntax"
690 "Test %%prun with IPython special syntax"
689 @register_line_magic
691 @register_line_magic
690 def lmagic(line):
692 def lmagic(line):
691 ip = get_ipython()
693 ip = get_ipython()
692 ip.user_ns['lmagic_out'] = line
694 ip.user_ns['lmagic_out'] = line
693
695
694 # line mode test
696 # line mode test
695 _ip.run_line_magic('prun', '-q %lmagic my line')
697 _ip.run_line_magic('prun', '-q %lmagic my line')
696 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
698 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
697 # cell mode test
699 # cell mode test
698 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
700 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
699 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
701 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
700
702
701 @dec.skipif(execution.profile is None)
703 @dec.skipif(execution.profile is None)
702 def test_prun_quotes():
704 def test_prun_quotes():
703 "Test that prun does not clobber string escapes (GH #1302)"
705 "Test that prun does not clobber string escapes (GH #1302)"
704 _ip.magic(r"prun -q x = '\t'")
706 _ip.magic(r"prun -q x = '\t'")
705 nt.assert_equal(_ip.user_ns['x'], '\t')
707 nt.assert_equal(_ip.user_ns['x'], '\t')
706
708
707 def test_extension():
709 def test_extension():
708 # Debugging information for failures of this test
710 # Debugging information for failures of this test
709 print('sys.path:')
711 print('sys.path:')
710 for p in sys.path:
712 for p in sys.path:
711 print(' ', p)
713 print(' ', p)
712 print('CWD', os.getcwd())
714 print('CWD', os.getcwd())
713
715
714 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
716 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
715 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
717 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
716 sys.path.insert(0, daft_path)
718 sys.path.insert(0, daft_path)
717 try:
719 try:
718 _ip.user_ns.pop('arq', None)
720 _ip.user_ns.pop('arq', None)
719 invalidate_caches() # Clear import caches
721 invalidate_caches() # Clear import caches
720 _ip.magic("load_ext daft_extension")
722 _ip.magic("load_ext daft_extension")
721 nt.assert_equal(_ip.user_ns['arq'], 185)
723 nt.assert_equal(_ip.user_ns['arq'], 185)
722 _ip.magic("unload_ext daft_extension")
724 _ip.magic("unload_ext daft_extension")
723 assert 'arq' not in _ip.user_ns
725 assert 'arq' not in _ip.user_ns
724 finally:
726 finally:
725 sys.path.remove(daft_path)
727 sys.path.remove(daft_path)
726
728
727
729
728 def test_notebook_export_json():
730 def test_notebook_export_json():
729 _ip = get_ipython()
731 _ip = get_ipython()
730 _ip.history_manager.reset() # Clear any existing history.
732 _ip.history_manager.reset() # Clear any existing history.
731 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
733 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
732 for i, cmd in enumerate(cmds, start=1):
734 for i, cmd in enumerate(cmds, start=1):
733 _ip.history_manager.store_inputs(i, cmd)
735 _ip.history_manager.store_inputs(i, cmd)
734 with TemporaryDirectory() as td:
736 with TemporaryDirectory() as td:
735 outfile = os.path.join(td, "nb.ipynb")
737 outfile = os.path.join(td, "nb.ipynb")
736 _ip.magic("notebook -e %s" % outfile)
738 _ip.magic("notebook -e %s" % outfile)
737
739
738
740
739 class TestEnv(TestCase):
741 class TestEnv(TestCase):
740
742
741 def test_env(self):
743 def test_env(self):
742 env = _ip.magic("env")
744 env = _ip.magic("env")
743 self.assertTrue(isinstance(env, dict))
745 self.assertTrue(isinstance(env, dict))
744
746
745 def test_env_secret(self):
747 def test_env_secret(self):
746 env = _ip.magic("env")
748 env = _ip.magic("env")
747 hidden = "<hidden>"
749 hidden = "<hidden>"
748 with mock.patch.dict(
750 with mock.patch.dict(
749 os.environ,
751 os.environ,
750 {
752 {
751 "API_KEY": "abc123",
753 "API_KEY": "abc123",
752 "SECRET_THING": "ssshhh",
754 "SECRET_THING": "ssshhh",
753 "JUPYTER_TOKEN": "",
755 "JUPYTER_TOKEN": "",
754 "VAR": "abc"
756 "VAR": "abc"
755 }
757 }
756 ):
758 ):
757 env = _ip.magic("env")
759 env = _ip.magic("env")
758 assert env["API_KEY"] == hidden
760 assert env["API_KEY"] == hidden
759 assert env["SECRET_THING"] == hidden
761 assert env["SECRET_THING"] == hidden
760 assert env["JUPYTER_TOKEN"] == hidden
762 assert env["JUPYTER_TOKEN"] == hidden
761 assert env["VAR"] == "abc"
763 assert env["VAR"] == "abc"
762
764
763 def test_env_get_set_simple(self):
765 def test_env_get_set_simple(self):
764 env = _ip.magic("env var val1")
766 env = _ip.magic("env var val1")
765 self.assertEqual(env, None)
767 self.assertEqual(env, None)
766 self.assertEqual(os.environ['var'], 'val1')
768 self.assertEqual(os.environ['var'], 'val1')
767 self.assertEqual(_ip.magic("env var"), 'val1')
769 self.assertEqual(_ip.magic("env var"), 'val1')
768 env = _ip.magic("env var=val2")
770 env = _ip.magic("env var=val2")
769 self.assertEqual(env, None)
771 self.assertEqual(env, None)
770 self.assertEqual(os.environ['var'], 'val2')
772 self.assertEqual(os.environ['var'], 'val2')
771
773
772 def test_env_get_set_complex(self):
774 def test_env_get_set_complex(self):
773 env = _ip.magic("env var 'val1 '' 'val2")
775 env = _ip.magic("env var 'val1 '' 'val2")
774 self.assertEqual(env, None)
776 self.assertEqual(env, None)
775 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
777 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
776 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
778 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
777 env = _ip.magic('env var=val2 val3="val4')
779 env = _ip.magic('env var=val2 val3="val4')
778 self.assertEqual(env, None)
780 self.assertEqual(env, None)
779 self.assertEqual(os.environ['var'], 'val2 val3="val4')
781 self.assertEqual(os.environ['var'], 'val2 val3="val4')
780
782
781 def test_env_set_bad_input(self):
783 def test_env_set_bad_input(self):
782 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
784 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
783
785
784 def test_env_set_whitespace(self):
786 def test_env_set_whitespace(self):
785 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
787 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
786
788
787
789
788 class CellMagicTestCase(TestCase):
790 class CellMagicTestCase(TestCase):
789
791
790 def check_ident(self, magic):
792 def check_ident(self, magic):
791 # Manually called, we get the result
793 # Manually called, we get the result
792 out = _ip.run_cell_magic(magic, 'a', 'b')
794 out = _ip.run_cell_magic(magic, 'a', 'b')
793 nt.assert_equal(out, ('a','b'))
795 nt.assert_equal(out, ('a','b'))
794 # Via run_cell, it goes into the user's namespace via displayhook
796 # Via run_cell, it goes into the user's namespace via displayhook
795 _ip.run_cell('%%' + magic +' c\nd\n')
797 _ip.run_cell('%%' + magic +' c\nd\n')
796 nt.assert_equal(_ip.user_ns['_'], ('c','d\n'))
798 nt.assert_equal(_ip.user_ns['_'], ('c','d\n'))
797
799
798 def test_cell_magic_func_deco(self):
800 def test_cell_magic_func_deco(self):
799 "Cell magic using simple decorator"
801 "Cell magic using simple decorator"
800 @register_cell_magic
802 @register_cell_magic
801 def cellm(line, cell):
803 def cellm(line, cell):
802 return line, cell
804 return line, cell
803
805
804 self.check_ident('cellm')
806 self.check_ident('cellm')
805
807
806 def test_cell_magic_reg(self):
808 def test_cell_magic_reg(self):
807 "Cell magic manually registered"
809 "Cell magic manually registered"
808 def cellm(line, cell):
810 def cellm(line, cell):
809 return line, cell
811 return line, cell
810
812
811 _ip.register_magic_function(cellm, 'cell', 'cellm2')
813 _ip.register_magic_function(cellm, 'cell', 'cellm2')
812 self.check_ident('cellm2')
814 self.check_ident('cellm2')
813
815
814 def test_cell_magic_class(self):
816 def test_cell_magic_class(self):
815 "Cell magics declared via a class"
817 "Cell magics declared via a class"
816 @magics_class
818 @magics_class
817 class MyMagics(Magics):
819 class MyMagics(Magics):
818
820
819 @cell_magic
821 @cell_magic
820 def cellm3(self, line, cell):
822 def cellm3(self, line, cell):
821 return line, cell
823 return line, cell
822
824
823 _ip.register_magics(MyMagics)
825 _ip.register_magics(MyMagics)
824 self.check_ident('cellm3')
826 self.check_ident('cellm3')
825
827
826 def test_cell_magic_class2(self):
828 def test_cell_magic_class2(self):
827 "Cell magics declared via a class, #2"
829 "Cell magics declared via a class, #2"
828 @magics_class
830 @magics_class
829 class MyMagics2(Magics):
831 class MyMagics2(Magics):
830
832
831 @cell_magic('cellm4')
833 @cell_magic('cellm4')
832 def cellm33(self, line, cell):
834 def cellm33(self, line, cell):
833 return line, cell
835 return line, cell
834
836
835 _ip.register_magics(MyMagics2)
837 _ip.register_magics(MyMagics2)
836 self.check_ident('cellm4')
838 self.check_ident('cellm4')
837 # Check that nothing is registered as 'cellm33'
839 # Check that nothing is registered as 'cellm33'
838 c33 = _ip.find_cell_magic('cellm33')
840 c33 = _ip.find_cell_magic('cellm33')
839 nt.assert_equal(c33, None)
841 nt.assert_equal(c33, None)
840
842
841 def test_file():
843 def test_file():
842 """Basic %%writefile"""
844 """Basic %%writefile"""
843 ip = get_ipython()
845 ip = get_ipython()
844 with TemporaryDirectory() as td:
846 with TemporaryDirectory() as td:
845 fname = os.path.join(td, 'file1')
847 fname = os.path.join(td, 'file1')
846 ip.run_cell_magic("writefile", fname, u'\n'.join([
848 ip.run_cell_magic("writefile", fname, u'\n'.join([
847 'line1',
849 'line1',
848 'line2',
850 'line2',
849 ]))
851 ]))
850 s = Path(fname).read_text()
852 s = Path(fname).read_text()
851 nt.assert_in('line1\n', s)
853 nt.assert_in('line1\n', s)
852 nt.assert_in('line2', s)
854 nt.assert_in('line2', s)
853
855
854 @dec.skip_win32
856 @dec.skip_win32
855 def test_file_single_quote():
857 def test_file_single_quote():
856 """Basic %%writefile with embedded single quotes"""
858 """Basic %%writefile with embedded single quotes"""
857 ip = get_ipython()
859 ip = get_ipython()
858 with TemporaryDirectory() as td:
860 with TemporaryDirectory() as td:
859 fname = os.path.join(td, '\'file1\'')
861 fname = os.path.join(td, '\'file1\'')
860 ip.run_cell_magic("writefile", fname, u'\n'.join([
862 ip.run_cell_magic("writefile", fname, u'\n'.join([
861 'line1',
863 'line1',
862 'line2',
864 'line2',
863 ]))
865 ]))
864 s = Path(fname).read_text()
866 s = Path(fname).read_text()
865 nt.assert_in('line1\n', s)
867 nt.assert_in('line1\n', s)
866 nt.assert_in('line2', s)
868 nt.assert_in('line2', s)
867
869
868 @dec.skip_win32
870 @dec.skip_win32
869 def test_file_double_quote():
871 def test_file_double_quote():
870 """Basic %%writefile with embedded double quotes"""
872 """Basic %%writefile with embedded double quotes"""
871 ip = get_ipython()
873 ip = get_ipython()
872 with TemporaryDirectory() as td:
874 with TemporaryDirectory() as td:
873 fname = os.path.join(td, '"file1"')
875 fname = os.path.join(td, '"file1"')
874 ip.run_cell_magic("writefile", fname, u'\n'.join([
876 ip.run_cell_magic("writefile", fname, u'\n'.join([
875 'line1',
877 'line1',
876 'line2',
878 'line2',
877 ]))
879 ]))
878 s = Path(fname).read_text()
880 s = Path(fname).read_text()
879 nt.assert_in('line1\n', s)
881 nt.assert_in('line1\n', s)
880 nt.assert_in('line2', s)
882 nt.assert_in('line2', s)
881
883
882 def test_file_var_expand():
884 def test_file_var_expand():
883 """%%writefile $filename"""
885 """%%writefile $filename"""
884 ip = get_ipython()
886 ip = get_ipython()
885 with TemporaryDirectory() as td:
887 with TemporaryDirectory() as td:
886 fname = os.path.join(td, 'file1')
888 fname = os.path.join(td, 'file1')
887 ip.user_ns['filename'] = fname
889 ip.user_ns['filename'] = fname
888 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
890 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
889 'line1',
891 'line1',
890 'line2',
892 'line2',
891 ]))
893 ]))
892 s = Path(fname).read_text()
894 s = Path(fname).read_text()
893 nt.assert_in('line1\n', s)
895 nt.assert_in('line1\n', s)
894 nt.assert_in('line2', s)
896 nt.assert_in('line2', s)
895
897
896 def test_file_unicode():
898 def test_file_unicode():
897 """%%writefile with unicode cell"""
899 """%%writefile with unicode cell"""
898 ip = get_ipython()
900 ip = get_ipython()
899 with TemporaryDirectory() as td:
901 with TemporaryDirectory() as td:
900 fname = os.path.join(td, 'file1')
902 fname = os.path.join(td, 'file1')
901 ip.run_cell_magic("writefile", fname, u'\n'.join([
903 ip.run_cell_magic("writefile", fname, u'\n'.join([
902 u'linΓ©1',
904 u'linΓ©1',
903 u'linΓ©2',
905 u'linΓ©2',
904 ]))
906 ]))
905 with io.open(fname, encoding='utf-8') as f:
907 with io.open(fname, encoding='utf-8') as f:
906 s = f.read()
908 s = f.read()
907 nt.assert_in(u'linΓ©1\n', s)
909 nt.assert_in(u'linΓ©1\n', s)
908 nt.assert_in(u'linΓ©2', s)
910 nt.assert_in(u'linΓ©2', s)
909
911
910 def test_file_amend():
912 def test_file_amend():
911 """%%writefile -a amends files"""
913 """%%writefile -a amends files"""
912 ip = get_ipython()
914 ip = get_ipython()
913 with TemporaryDirectory() as td:
915 with TemporaryDirectory() as td:
914 fname = os.path.join(td, 'file2')
916 fname = os.path.join(td, 'file2')
915 ip.run_cell_magic("writefile", fname, u'\n'.join([
917 ip.run_cell_magic("writefile", fname, u'\n'.join([
916 'line1',
918 'line1',
917 'line2',
919 'line2',
918 ]))
920 ]))
919 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
921 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
920 'line3',
922 'line3',
921 'line4',
923 'line4',
922 ]))
924 ]))
923 s = Path(fname).read_text()
925 s = Path(fname).read_text()
924 nt.assert_in('line1\n', s)
926 nt.assert_in('line1\n', s)
925 nt.assert_in('line3\n', s)
927 nt.assert_in('line3\n', s)
926
928
927 def test_file_spaces():
929 def test_file_spaces():
928 """%%file with spaces in filename"""
930 """%%file with spaces in filename"""
929 ip = get_ipython()
931 ip = get_ipython()
930 with TemporaryWorkingDirectory() as td:
932 with TemporaryWorkingDirectory() as td:
931 fname = "file name"
933 fname = "file name"
932 ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([
934 ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([
933 'line1',
935 'line1',
934 'line2',
936 'line2',
935 ]))
937 ]))
936 s = Path(fname).read_text()
938 s = Path(fname).read_text()
937 nt.assert_in('line1\n', s)
939 nt.assert_in('line1\n', s)
938 nt.assert_in('line2', s)
940 nt.assert_in('line2', s)
939
941
940 def test_script_config():
942 def test_script_config():
941 ip = get_ipython()
943 ip = get_ipython()
942 ip.config.ScriptMagics.script_magics = ['whoda']
944 ip.config.ScriptMagics.script_magics = ['whoda']
943 sm = script.ScriptMagics(shell=ip)
945 sm = script.ScriptMagics(shell=ip)
944 nt.assert_in('whoda', sm.magics['cell'])
946 nt.assert_in('whoda', sm.magics['cell'])
945
947
946 @dec.skip_win32
948 @dec.skip_win32
947 def test_script_out():
949 def test_script_out():
948 ip = get_ipython()
950 ip = get_ipython()
949 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
951 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
950 nt.assert_equal(ip.user_ns['output'], 'hi\n')
952 nt.assert_equal(ip.user_ns['output'], 'hi\n')
951
953
952 @dec.skip_win32
954 @dec.skip_win32
953 def test_script_err():
955 def test_script_err():
954 ip = get_ipython()
956 ip = get_ipython()
955 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
957 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
956 nt.assert_equal(ip.user_ns['error'], 'hello\n')
958 nt.assert_equal(ip.user_ns['error'], 'hello\n')
957
959
958 @dec.skip_win32
960 @dec.skip_win32
959 def test_script_out_err():
961 def test_script_out_err():
960 ip = get_ipython()
962 ip = get_ipython()
961 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
963 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
962 nt.assert_equal(ip.user_ns['output'], 'hi\n')
964 nt.assert_equal(ip.user_ns['output'], 'hi\n')
963 nt.assert_equal(ip.user_ns['error'], 'hello\n')
965 nt.assert_equal(ip.user_ns['error'], 'hello\n')
964
966
965 @dec.skip_win32
967 @dec.skip_win32
966 async def test_script_bg_out():
968 async def test_script_bg_out():
967 ip = get_ipython()
969 ip = get_ipython()
968 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
970 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
969 nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n")
971 nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n")
970 ip.user_ns['output'].close()
972 ip.user_ns['output'].close()
971
973
972
974
973 @dec.skip_win32
975 @dec.skip_win32
974 async def test_script_bg_err():
976 async def test_script_bg_err():
975 ip = get_ipython()
977 ip = get_ipython()
976 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
978 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
977 nt.assert_equal((await ip.user_ns["error"].read()), b"hello\n")
979 nt.assert_equal((await ip.user_ns["error"].read()), b"hello\n")
978 ip.user_ns["error"].close()
980 ip.user_ns["error"].close()
979
981
980
982
981 @dec.skip_win32
983 @dec.skip_win32
982 async def test_script_bg_out_err():
984 async def test_script_bg_out_err():
983 ip = get_ipython()
985 ip = get_ipython()
984 ip.run_cell_magic(
986 ip.run_cell_magic(
985 "script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2"
987 "script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2"
986 )
988 )
987 nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n")
989 nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n")
988 nt.assert_equal((await ip.user_ns["error"].read()), b"hello\n")
990 nt.assert_equal((await ip.user_ns["error"].read()), b"hello\n")
989 ip.user_ns["output"].close()
991 ip.user_ns["output"].close()
990 ip.user_ns["error"].close()
992 ip.user_ns["error"].close()
991
993
992
994
993 def test_script_defaults():
995 def test_script_defaults():
994 ip = get_ipython()
996 ip = get_ipython()
995 for cmd in ['sh', 'bash', 'perl', 'ruby']:
997 for cmd in ['sh', 'bash', 'perl', 'ruby']:
996 try:
998 try:
997 find_cmd(cmd)
999 find_cmd(cmd)
998 except Exception:
1000 except Exception:
999 pass
1001 pass
1000 else:
1002 else:
1001 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
1003 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
1002
1004
1003
1005
1004 @magics_class
1006 @magics_class
1005 class FooFoo(Magics):
1007 class FooFoo(Magics):
1006 """class with both %foo and %%foo magics"""
1008 """class with both %foo and %%foo magics"""
1007 @line_magic('foo')
1009 @line_magic('foo')
1008 def line_foo(self, line):
1010 def line_foo(self, line):
1009 "I am line foo"
1011 "I am line foo"
1010 pass
1012 pass
1011
1013
1012 @cell_magic("foo")
1014 @cell_magic("foo")
1013 def cell_foo(self, line, cell):
1015 def cell_foo(self, line, cell):
1014 "I am cell foo, not line foo"
1016 "I am cell foo, not line foo"
1015 pass
1017 pass
1016
1018
1017 def test_line_cell_info():
1019 def test_line_cell_info():
1018 """%%foo and %foo magics are distinguishable to inspect"""
1020 """%%foo and %foo magics are distinguishable to inspect"""
1019 ip = get_ipython()
1021 ip = get_ipython()
1020 ip.magics_manager.register(FooFoo)
1022 ip.magics_manager.register(FooFoo)
1021 oinfo = ip.object_inspect('foo')
1023 oinfo = ip.object_inspect('foo')
1022 nt.assert_true(oinfo['found'])
1024 nt.assert_true(oinfo['found'])
1023 nt.assert_true(oinfo['ismagic'])
1025 nt.assert_true(oinfo['ismagic'])
1024
1026
1025 oinfo = ip.object_inspect('%%foo')
1027 oinfo = ip.object_inspect('%%foo')
1026 nt.assert_true(oinfo['found'])
1028 nt.assert_true(oinfo['found'])
1027 nt.assert_true(oinfo['ismagic'])
1029 nt.assert_true(oinfo['ismagic'])
1028 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
1030 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
1029
1031
1030 oinfo = ip.object_inspect('%foo')
1032 oinfo = ip.object_inspect('%foo')
1031 nt.assert_true(oinfo['found'])
1033 nt.assert_true(oinfo['found'])
1032 nt.assert_true(oinfo['ismagic'])
1034 nt.assert_true(oinfo['ismagic'])
1033 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
1035 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
1034
1036
1035 def test_multiple_magics():
1037 def test_multiple_magics():
1036 ip = get_ipython()
1038 ip = get_ipython()
1037 foo1 = FooFoo(ip)
1039 foo1 = FooFoo(ip)
1038 foo2 = FooFoo(ip)
1040 foo2 = FooFoo(ip)
1039 mm = ip.magics_manager
1041 mm = ip.magics_manager
1040 mm.register(foo1)
1042 mm.register(foo1)
1041 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
1043 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
1042 mm.register(foo2)
1044 mm.register(foo2)
1043 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
1045 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
1044
1046
1045 def test_alias_magic():
1047 def test_alias_magic():
1046 """Test %alias_magic."""
1048 """Test %alias_magic."""
1047 ip = get_ipython()
1049 ip = get_ipython()
1048 mm = ip.magics_manager
1050 mm = ip.magics_manager
1049
1051
1050 # Basic operation: both cell and line magics are created, if possible.
1052 # Basic operation: both cell and line magics are created, if possible.
1051 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
1053 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
1052 nt.assert_in('timeit_alias', mm.magics['line'])
1054 nt.assert_in('timeit_alias', mm.magics['line'])
1053 nt.assert_in('timeit_alias', mm.magics['cell'])
1055 nt.assert_in('timeit_alias', mm.magics['cell'])
1054
1056
1055 # --cell is specified, line magic not created.
1057 # --cell is specified, line magic not created.
1056 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
1058 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
1057 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
1059 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
1058 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
1060 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
1059
1061
1060 # Test that line alias is created successfully.
1062 # Test that line alias is created successfully.
1061 ip.run_line_magic('alias_magic', '--line env_alias env')
1063 ip.run_line_magic('alias_magic', '--line env_alias env')
1062 nt.assert_equal(ip.run_line_magic('env', ''),
1064 nt.assert_equal(ip.run_line_magic('env', ''),
1063 ip.run_line_magic('env_alias', ''))
1065 ip.run_line_magic('env_alias', ''))
1064
1066
1065 # Test that line alias with parameters passed in is created successfully.
1067 # Test that line alias with parameters passed in is created successfully.
1066 ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3'))
1068 ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3'))
1067 nt.assert_in('history_alias', mm.magics['line'])
1069 nt.assert_in('history_alias', mm.magics['line'])
1068
1070
1069
1071
1070 def test_save():
1072 def test_save():
1071 """Test %save."""
1073 """Test %save."""
1072 ip = get_ipython()
1074 ip = get_ipython()
1073 ip.history_manager.reset() # Clear any existing history.
1075 ip.history_manager.reset() # Clear any existing history.
1074 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
1076 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
1075 for i, cmd in enumerate(cmds, start=1):
1077 for i, cmd in enumerate(cmds, start=1):
1076 ip.history_manager.store_inputs(i, cmd)
1078 ip.history_manager.store_inputs(i, cmd)
1077 with TemporaryDirectory() as tmpdir:
1079 with TemporaryDirectory() as tmpdir:
1078 file = os.path.join(tmpdir, "testsave.py")
1080 file = os.path.join(tmpdir, "testsave.py")
1079 ip.run_line_magic("save", "%s 1-10" % file)
1081 ip.run_line_magic("save", "%s 1-10" % file)
1080 content = Path(file).read_text()
1082 content = Path(file).read_text()
1081 nt.assert_equal(content.count(cmds[0]), 1)
1083 nt.assert_equal(content.count(cmds[0]), 1)
1082 nt.assert_in("coding: utf-8", content)
1084 nt.assert_in("coding: utf-8", content)
1083 ip.run_line_magic("save", "-a %s 1-10" % file)
1085 ip.run_line_magic("save", "-a %s 1-10" % file)
1084 content = Path(file).read_text()
1086 content = Path(file).read_text()
1085 nt.assert_equal(content.count(cmds[0]), 2)
1087 nt.assert_equal(content.count(cmds[0]), 2)
1086 nt.assert_in("coding: utf-8", content)
1088 nt.assert_in("coding: utf-8", content)
1087
1089
1088
1090
1089 def test_store():
1091 def test_store():
1090 """Test %store."""
1092 """Test %store."""
1091 ip = get_ipython()
1093 ip = get_ipython()
1092 ip.run_line_magic('load_ext', 'storemagic')
1094 ip.run_line_magic('load_ext', 'storemagic')
1093
1095
1094 # make sure the storage is empty
1096 # make sure the storage is empty
1095 ip.run_line_magic('store', '-z')
1097 ip.run_line_magic('store', '-z')
1096 ip.user_ns['var'] = 42
1098 ip.user_ns['var'] = 42
1097 ip.run_line_magic('store', 'var')
1099 ip.run_line_magic('store', 'var')
1098 ip.user_ns['var'] = 39
1100 ip.user_ns['var'] = 39
1099 ip.run_line_magic('store', '-r')
1101 ip.run_line_magic('store', '-r')
1100 nt.assert_equal(ip.user_ns['var'], 42)
1102 nt.assert_equal(ip.user_ns['var'], 42)
1101
1103
1102 ip.run_line_magic('store', '-d var')
1104 ip.run_line_magic('store', '-d var')
1103 ip.user_ns['var'] = 39
1105 ip.user_ns['var'] = 39
1104 ip.run_line_magic('store' , '-r')
1106 ip.run_line_magic('store' , '-r')
1105 nt.assert_equal(ip.user_ns['var'], 39)
1107 nt.assert_equal(ip.user_ns['var'], 39)
1106
1108
1107
1109
1108 def _run_edit_test(arg_s, exp_filename=None,
1110 def _run_edit_test(arg_s, exp_filename=None,
1109 exp_lineno=-1,
1111 exp_lineno=-1,
1110 exp_contents=None,
1112 exp_contents=None,
1111 exp_is_temp=None):
1113 exp_is_temp=None):
1112 ip = get_ipython()
1114 ip = get_ipython()
1113 M = code.CodeMagics(ip)
1115 M = code.CodeMagics(ip)
1114 last_call = ['','']
1116 last_call = ['','']
1115 opts,args = M.parse_options(arg_s,'prxn:')
1117 opts,args = M.parse_options(arg_s,'prxn:')
1116 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1118 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1117
1119
1118 if exp_filename is not None:
1120 if exp_filename is not None:
1119 nt.assert_equal(exp_filename, filename)
1121 nt.assert_equal(exp_filename, filename)
1120 if exp_contents is not None:
1122 if exp_contents is not None:
1121 with io.open(filename, 'r', encoding='utf-8') as f:
1123 with io.open(filename, 'r', encoding='utf-8') as f:
1122 contents = f.read()
1124 contents = f.read()
1123 nt.assert_equal(exp_contents, contents)
1125 nt.assert_equal(exp_contents, contents)
1124 if exp_lineno != -1:
1126 if exp_lineno != -1:
1125 nt.assert_equal(exp_lineno, lineno)
1127 nt.assert_equal(exp_lineno, lineno)
1126 if exp_is_temp is not None:
1128 if exp_is_temp is not None:
1127 nt.assert_equal(exp_is_temp, is_temp)
1129 nt.assert_equal(exp_is_temp, is_temp)
1128
1130
1129
1131
1130 def test_edit_interactive():
1132 def test_edit_interactive():
1131 """%edit on interactively defined objects"""
1133 """%edit on interactively defined objects"""
1132 ip = get_ipython()
1134 ip = get_ipython()
1133 n = ip.execution_count
1135 n = ip.execution_count
1134 ip.run_cell(u"def foo(): return 1", store_history=True)
1136 ip.run_cell(u"def foo(): return 1", store_history=True)
1135
1137
1136 try:
1138 try:
1137 _run_edit_test("foo")
1139 _run_edit_test("foo")
1138 except code.InteractivelyDefined as e:
1140 except code.InteractivelyDefined as e:
1139 nt.assert_equal(e.index, n)
1141 nt.assert_equal(e.index, n)
1140 else:
1142 else:
1141 raise AssertionError("Should have raised InteractivelyDefined")
1143 raise AssertionError("Should have raised InteractivelyDefined")
1142
1144
1143
1145
1144 def test_edit_cell():
1146 def test_edit_cell():
1145 """%edit [cell id]"""
1147 """%edit [cell id]"""
1146 ip = get_ipython()
1148 ip = get_ipython()
1147
1149
1148 ip.run_cell(u"def foo(): return 1", store_history=True)
1150 ip.run_cell(u"def foo(): return 1", store_history=True)
1149
1151
1150 # test
1152 # test
1151 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1153 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1152
1154
1153 def test_edit_fname():
1155 def test_edit_fname():
1154 """%edit file"""
1156 """%edit file"""
1155 # test
1157 # test
1156 _run_edit_test("test file.py", exp_filename="test file.py")
1158 _run_edit_test("test file.py", exp_filename="test file.py")
1157
1159
1158 def test_bookmark():
1160 def test_bookmark():
1159 ip = get_ipython()
1161 ip = get_ipython()
1160 ip.run_line_magic('bookmark', 'bmname')
1162 ip.run_line_magic('bookmark', 'bmname')
1161 with tt.AssertPrints('bmname'):
1163 with tt.AssertPrints('bmname'):
1162 ip.run_line_magic('bookmark', '-l')
1164 ip.run_line_magic('bookmark', '-l')
1163 ip.run_line_magic('bookmark', '-d bmname')
1165 ip.run_line_magic('bookmark', '-d bmname')
1164
1166
1165 def test_ls_magic():
1167 def test_ls_magic():
1166 ip = get_ipython()
1168 ip = get_ipython()
1167 json_formatter = ip.display_formatter.formatters['application/json']
1169 json_formatter = ip.display_formatter.formatters['application/json']
1168 json_formatter.enabled = True
1170 json_formatter.enabled = True
1169 lsmagic = ip.magic('lsmagic')
1171 lsmagic = ip.magic('lsmagic')
1170 with warnings.catch_warnings(record=True) as w:
1172 with warnings.catch_warnings(record=True) as w:
1171 j = json_formatter(lsmagic)
1173 j = json_formatter(lsmagic)
1172 nt.assert_equal(sorted(j), ['cell', 'line'])
1174 nt.assert_equal(sorted(j), ['cell', 'line'])
1173 nt.assert_equal(w, []) # no warnings
1175 nt.assert_equal(w, []) # no warnings
1174
1176
1175 def test_strip_initial_indent():
1177 def test_strip_initial_indent():
1176 def sii(s):
1178 def sii(s):
1177 lines = s.splitlines()
1179 lines = s.splitlines()
1178 return '\n'.join(code.strip_initial_indent(lines))
1180 return '\n'.join(code.strip_initial_indent(lines))
1179
1181
1180 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
1182 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
1181 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
1183 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
1182 nt.assert_equal(sii("a\n b"), "a\n b")
1184 nt.assert_equal(sii("a\n b"), "a\n b")
1183
1185
1184 def test_logging_magic_quiet_from_arg():
1186 def test_logging_magic_quiet_from_arg():
1185 _ip.config.LoggingMagics.quiet = False
1187 _ip.config.LoggingMagics.quiet = False
1186 lm = logging.LoggingMagics(shell=_ip)
1188 lm = logging.LoggingMagics(shell=_ip)
1187 with TemporaryDirectory() as td:
1189 with TemporaryDirectory() as td:
1188 try:
1190 try:
1189 with tt.AssertNotPrints(re.compile("Activating.*")):
1191 with tt.AssertNotPrints(re.compile("Activating.*")):
1190 lm.logstart('-q {}'.format(
1192 lm.logstart('-q {}'.format(
1191 os.path.join(td, "quiet_from_arg.log")))
1193 os.path.join(td, "quiet_from_arg.log")))
1192 finally:
1194 finally:
1193 _ip.logger.logstop()
1195 _ip.logger.logstop()
1194
1196
1195 def test_logging_magic_quiet_from_config():
1197 def test_logging_magic_quiet_from_config():
1196 _ip.config.LoggingMagics.quiet = True
1198 _ip.config.LoggingMagics.quiet = True
1197 lm = logging.LoggingMagics(shell=_ip)
1199 lm = logging.LoggingMagics(shell=_ip)
1198 with TemporaryDirectory() as td:
1200 with TemporaryDirectory() as td:
1199 try:
1201 try:
1200 with tt.AssertNotPrints(re.compile("Activating.*")):
1202 with tt.AssertNotPrints(re.compile("Activating.*")):
1201 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1203 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1202 finally:
1204 finally:
1203 _ip.logger.logstop()
1205 _ip.logger.logstop()
1204
1206
1205
1207
1206 def test_logging_magic_not_quiet():
1208 def test_logging_magic_not_quiet():
1207 _ip.config.LoggingMagics.quiet = False
1209 _ip.config.LoggingMagics.quiet = False
1208 lm = logging.LoggingMagics(shell=_ip)
1210 lm = logging.LoggingMagics(shell=_ip)
1209 with TemporaryDirectory() as td:
1211 with TemporaryDirectory() as td:
1210 try:
1212 try:
1211 with tt.AssertPrints(re.compile("Activating.*")):
1213 with tt.AssertPrints(re.compile("Activating.*")):
1212 lm.logstart(os.path.join(td, "not_quiet.log"))
1214 lm.logstart(os.path.join(td, "not_quiet.log"))
1213 finally:
1215 finally:
1214 _ip.logger.logstop()
1216 _ip.logger.logstop()
1215
1217
1216
1218
1217 def test_time_no_var_expand():
1219 def test_time_no_var_expand():
1218 _ip.user_ns['a'] = 5
1220 _ip.user_ns['a'] = 5
1219 _ip.user_ns['b'] = []
1221 _ip.user_ns['b'] = []
1220 _ip.magic('time b.append("{a}")')
1222 _ip.magic('time b.append("{a}")')
1221 assert _ip.user_ns['b'] == ['{a}']
1223 assert _ip.user_ns['b'] == ['{a}']
1222
1224
1223
1225
1224 # this is slow, put at the end for local testing.
1226 # this is slow, put at the end for local testing.
1225 def test_timeit_arguments():
1227 def test_timeit_arguments():
1226 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1228 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1227 if sys.version_info < (3,7):
1229 if sys.version_info < (3,7):
1228 _ip.magic("timeit -n1 -r1 ('#')")
1230 _ip.magic("timeit -n1 -r1 ('#')")
1229 else:
1231 else:
1230 # 3.7 optimize no-op statement like above out, and complain there is
1232 # 3.7 optimize no-op statement like above out, and complain there is
1231 # nothing in the for loop.
1233 # nothing in the for loop.
1232 _ip.magic("timeit -n1 -r1 a=('#')")
1234 _ip.magic("timeit -n1 -r1 a=('#')")
1233
1235
1234
1236
1235 TEST_MODULE = """
1237 TEST_MODULE = """
1236 print('Loaded my_tmp')
1238 print('Loaded my_tmp')
1237 if __name__ == "__main__":
1239 if __name__ == "__main__":
1238 print('I just ran a script')
1240 print('I just ran a script')
1239 """
1241 """
1240
1242
1241
1243
1242 def test_run_module_from_import_hook():
1244 def test_run_module_from_import_hook():
1243 "Test that a module can be loaded via an import hook"
1245 "Test that a module can be loaded via an import hook"
1244 with TemporaryDirectory() as tmpdir:
1246 with TemporaryDirectory() as tmpdir:
1245 fullpath = os.path.join(tmpdir, 'my_tmp.py')
1247 fullpath = os.path.join(tmpdir, 'my_tmp.py')
1246 Path(fullpath).write_text(TEST_MODULE)
1248 Path(fullpath).write_text(TEST_MODULE)
1247
1249
1248 class MyTempImporter(object):
1250 class MyTempImporter(object):
1249 def __init__(self):
1251 def __init__(self):
1250 pass
1252 pass
1251
1253
1252 def find_module(self, fullname, path=None):
1254 def find_module(self, fullname, path=None):
1253 if 'my_tmp' in fullname:
1255 if 'my_tmp' in fullname:
1254 return self
1256 return self
1255 return None
1257 return None
1256
1258
1257 def load_module(self, name):
1259 def load_module(self, name):
1258 import imp
1260 import imp
1259 return imp.load_source('my_tmp', fullpath)
1261 return imp.load_source('my_tmp', fullpath)
1260
1262
1261 def get_code(self, fullname):
1263 def get_code(self, fullname):
1262 return compile(Path(fullpath).read_text(), "foo", "exec")
1264 return compile(Path(fullpath).read_text(), "foo", "exec")
1263
1265
1264 def is_package(self, __):
1266 def is_package(self, __):
1265 return False
1267 return False
1266
1268
1267 sys.meta_path.insert(0, MyTempImporter())
1269 sys.meta_path.insert(0, MyTempImporter())
1268
1270
1269 with capture_output() as captured:
1271 with capture_output() as captured:
1270 _ip.magic("run -m my_tmp")
1272 _ip.magic("run -m my_tmp")
1271 _ip.run_cell("import my_tmp")
1273 _ip.run_cell("import my_tmp")
1272
1274
1273 output = "Loaded my_tmp\nI just ran a script\nLoaded my_tmp\n"
1275 output = "Loaded my_tmp\nI just ran a script\nLoaded my_tmp\n"
1274 nt.assert_equal(output, captured.stdout)
1276 nt.assert_equal(output, captured.stdout)
1275
1277
1276 sys.meta_path.pop(0)
1278 sys.meta_path.pop(0)
General Comments 0
You need to be logged in to leave comments. Login now