##// END OF EJS Templates
Remove unneeded `skip_doctest` decorator usages
Nikita Kniazev -
Show More
@@ -1,1109 +1,1106 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5
5
6 This is an extension to PDB which adds a number of new features.
6 This is an extension to PDB which adds a number of new features.
7 Note that there is also the `IPython.terminal.debugger` class which provides UI
7 Note that there is also the `IPython.terminal.debugger` class which provides UI
8 improvements.
8 improvements.
9
9
10 We also strongly recommend to use this via the `ipdb` package, which provides
10 We also strongly recommend to use this via the `ipdb` package, which provides
11 extra configuration options.
11 extra configuration options.
12
12
13 Among other things, this subclass of PDB:
13 Among other things, this subclass of PDB:
14 - supports many IPython magics like pdef/psource
14 - supports many IPython magics like pdef/psource
15 - hide frames in tracebacks based on `__tracebackhide__`
15 - hide frames in tracebacks based on `__tracebackhide__`
16 - allows to skip frames based on `__debuggerskip__`
16 - allows to skip frames based on `__debuggerskip__`
17
17
18 The skipping and hiding frames are configurable via the `skip_predicates`
18 The skipping and hiding frames are configurable via the `skip_predicates`
19 command.
19 command.
20
20
21 By default, frames from readonly files will be hidden, frames containing
21 By default, frames from readonly files will be hidden, frames containing
22 ``__tracebackhide__=True`` will be hidden.
22 ``__tracebackhide__=True`` will be hidden.
23
23
24 Frames containing ``__debuggerskip__`` will be stepped over, frames who's parent
24 Frames containing ``__debuggerskip__`` will be stepped over, frames who's parent
25 frames value of ``__debuggerskip__`` is ``True`` will be skipped.
25 frames value of ``__debuggerskip__`` is ``True`` will be skipped.
26
26
27 >>> def helpers_helper():
27 >>> def helpers_helper():
28 ... pass
28 ... pass
29 ...
29 ...
30 ... def helper_1():
30 ... def helper_1():
31 ... print("don't step in me")
31 ... print("don't step in me")
32 ... helpers_helpers() # will be stepped over unless breakpoint set.
32 ... helpers_helpers() # will be stepped over unless breakpoint set.
33 ...
33 ...
34 ...
34 ...
35 ... def helper_2():
35 ... def helper_2():
36 ... print("in me neither")
36 ... print("in me neither")
37 ...
37 ...
38
38
39 One can define a decorator that wraps a function between the two helpers:
39 One can define a decorator that wraps a function between the two helpers:
40
40
41 >>> def pdb_skipped_decorator(function):
41 >>> def pdb_skipped_decorator(function):
42 ...
42 ...
43 ...
43 ...
44 ... def wrapped_fn(*args, **kwargs):
44 ... def wrapped_fn(*args, **kwargs):
45 ... __debuggerskip__ = True
45 ... __debuggerskip__ = True
46 ... helper_1()
46 ... helper_1()
47 ... __debuggerskip__ = False
47 ... __debuggerskip__ = False
48 ... result = function(*args, **kwargs)
48 ... result = function(*args, **kwargs)
49 ... __debuggerskip__ = True
49 ... __debuggerskip__ = True
50 ... helper_2()
50 ... helper_2()
51 ... # setting __debuggerskip__ to False again is not necessary
51 ... # setting __debuggerskip__ to False again is not necessary
52 ... return result
52 ... return result
53 ...
53 ...
54 ... return wrapped_fn
54 ... return wrapped_fn
55
55
56 When decorating a function, ipdb will directly step into ``bar()`` by
56 When decorating a function, ipdb will directly step into ``bar()`` by
57 default:
57 default:
58
58
59 >>> @foo_decorator
59 >>> @foo_decorator
60 ... def bar(x, y):
60 ... def bar(x, y):
61 ... return x * y
61 ... return x * y
62
62
63
63
64 You can toggle the behavior with
64 You can toggle the behavior with
65
65
66 ipdb> skip_predicates debuggerskip false
66 ipdb> skip_predicates debuggerskip false
67
67
68 or configure it in your ``.pdbrc``
68 or configure it in your ``.pdbrc``
69
69
70
70
71
71
72 License
72 License
73 -------
73 -------
74
74
75 Modified from the standard pdb.Pdb class to avoid including readline, so that
75 Modified from the standard pdb.Pdb class to avoid including readline, so that
76 the command line completion of other programs which include this isn't
76 the command line completion of other programs which include this isn't
77 damaged.
77 damaged.
78
78
79 In the future, this class will be expanded with improvements over the standard
79 In the future, this class will be expanded with improvements over the standard
80 pdb.
80 pdb.
81
81
82 The original code in this file is mainly lifted out of cmd.py in Python 2.2,
82 The original code in this file is mainly lifted out of cmd.py in Python 2.2,
83 with minor changes. Licensing should therefore be under the standard Python
83 with minor changes. Licensing should therefore be under the standard Python
84 terms. For details on the PSF (Python Software Foundation) standard license,
84 terms. For details on the PSF (Python Software Foundation) standard license,
85 see:
85 see:
86
86
87 https://docs.python.org/2/license.html
87 https://docs.python.org/2/license.html
88
88
89
89
90 All the changes since then are under the same license as IPython.
90 All the changes since then are under the same license as IPython.
91
91
92 """
92 """
93
93
94 #*****************************************************************************
94 #*****************************************************************************
95 #
95 #
96 # This file is licensed under the PSF license.
96 # This file is licensed under the PSF license.
97 #
97 #
98 # Copyright (C) 2001 Python Software Foundation, www.python.org
98 # Copyright (C) 2001 Python Software Foundation, www.python.org
99 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
99 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
100 #
100 #
101 #
101 #
102 #*****************************************************************************
102 #*****************************************************************************
103
103
104 import bdb
104 import bdb
105 import functools
105 import functools
106 import inspect
106 import inspect
107 import linecache
107 import linecache
108 import sys
108 import sys
109 import warnings
109 import warnings
110 import re
110 import re
111 import os
111 import os
112
112
113 from IPython import get_ipython
113 from IPython import get_ipython
114 from IPython.utils import PyColorize
114 from IPython.utils import PyColorize
115 from IPython.utils import coloransi, py3compat
115 from IPython.utils import coloransi, py3compat
116 from IPython.core.excolors import exception_colors
116 from IPython.core.excolors import exception_colors
117 from IPython.testing.skipdoctest import skip_doctest
118
117
119 # skip module docstests
118 # skip module docstests
120 __skip_doctest__ = True
119 __skip_doctest__ = True
121
120
122 prompt = 'ipdb> '
121 prompt = 'ipdb> '
123
122
124 # We have to check this directly from sys.argv, config struct not yet available
123 # We have to check this directly from sys.argv, config struct not yet available
125 from pdb import Pdb as OldPdb
124 from pdb import Pdb as OldPdb
126
125
127 # Allow the set_trace code to operate outside of an ipython instance, even if
126 # Allow the set_trace code to operate outside of an ipython instance, even if
128 # it does so with some limitations. The rest of this support is implemented in
127 # it does so with some limitations. The rest of this support is implemented in
129 # the Tracer constructor.
128 # the Tracer constructor.
130
129
131 DEBUGGERSKIP = "__debuggerskip__"
130 DEBUGGERSKIP = "__debuggerskip__"
132
131
133
132
134 def make_arrow(pad):
133 def make_arrow(pad):
135 """generate the leading arrow in front of traceback or debugger"""
134 """generate the leading arrow in front of traceback or debugger"""
136 if pad >= 2:
135 if pad >= 2:
137 return '-'*(pad-2) + '> '
136 return '-'*(pad-2) + '> '
138 elif pad == 1:
137 elif pad == 1:
139 return '>'
138 return '>'
140 return ''
139 return ''
141
140
142
141
143 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
142 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
144 """Exception hook which handles `BdbQuit` exceptions.
143 """Exception hook which handles `BdbQuit` exceptions.
145
144
146 All other exceptions are processed using the `excepthook`
145 All other exceptions are processed using the `excepthook`
147 parameter.
146 parameter.
148 """
147 """
149 warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
148 warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
150 DeprecationWarning, stacklevel=2)
149 DeprecationWarning, stacklevel=2)
151 if et == bdb.BdbQuit:
150 if et == bdb.BdbQuit:
152 print('Exiting Debugger.')
151 print('Exiting Debugger.')
153 elif excepthook is not None:
152 elif excepthook is not None:
154 excepthook(et, ev, tb)
153 excepthook(et, ev, tb)
155 else:
154 else:
156 # Backwards compatibility. Raise deprecation warning?
155 # Backwards compatibility. Raise deprecation warning?
157 BdbQuit_excepthook.excepthook_ori(et, ev, tb)
156 BdbQuit_excepthook.excepthook_ori(et, ev, tb)
158
157
159
158
160 def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
159 def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
161 warnings.warn(
160 warnings.warn(
162 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
161 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
163 DeprecationWarning, stacklevel=2)
162 DeprecationWarning, stacklevel=2)
164 print('Exiting Debugger.')
163 print('Exiting Debugger.')
165
164
166
165
167 class Tracer(object):
166 class Tracer(object):
168 """
167 """
169 DEPRECATED
168 DEPRECATED
170
169
171 Class for local debugging, similar to pdb.set_trace.
170 Class for local debugging, similar to pdb.set_trace.
172
171
173 Instances of this class, when called, behave like pdb.set_trace, but
172 Instances of this class, when called, behave like pdb.set_trace, but
174 providing IPython's enhanced capabilities.
173 providing IPython's enhanced capabilities.
175
174
176 This is implemented as a class which must be initialized in your own code
175 This is implemented as a class which must be initialized in your own code
177 and not as a standalone function because we need to detect at runtime
176 and not as a standalone function because we need to detect at runtime
178 whether IPython is already active or not. That detection is done in the
177 whether IPython is already active or not. That detection is done in the
179 constructor, ensuring that this code plays nicely with a running IPython,
178 constructor, ensuring that this code plays nicely with a running IPython,
180 while functioning acceptably (though with limitations) if outside of it.
179 while functioning acceptably (though with limitations) if outside of it.
181 """
180 """
182
181
183 @skip_doctest
184 def __init__(self, colors=None):
182 def __init__(self, colors=None):
185 """
183 """
186 DEPRECATED
184 DEPRECATED
187
185
188 Create a local debugger instance.
186 Create a local debugger instance.
189
187
190 Parameters
188 Parameters
191 ----------
189 ----------
192 colors : str, optional
190 colors : str, optional
193 The name of the color scheme to use, it must be one of IPython's
191 The name of the color scheme to use, it must be one of IPython's
194 valid color schemes. If not given, the function will default to
192 valid color schemes. If not given, the function will default to
195 the current IPython scheme when running inside IPython, and to
193 the current IPython scheme when running inside IPython, and to
196 'NoColor' otherwise.
194 'NoColor' otherwise.
197
195
198 Examples
196 Examples
199 --------
197 --------
200 ::
198 ::
201
199
202 from IPython.core.debugger import Tracer; debug_here = Tracer()
200 from IPython.core.debugger import Tracer; debug_here = Tracer()
203
201
204 Later in your code::
202 Later in your code::
205
203
206 debug_here() # -> will open up the debugger at that point.
204 debug_here() # -> will open up the debugger at that point.
207
205
208 Once the debugger activates, you can use all of its regular commands to
206 Once the debugger activates, you can use all of its regular commands to
209 step through code, set breakpoints, etc. See the pdb documentation
207 step through code, set breakpoints, etc. See the pdb documentation
210 from the Python standard library for usage details.
208 from the Python standard library for usage details.
211 """
209 """
212 warnings.warn("`Tracer` is deprecated since version 5.1, directly use "
210 warnings.warn("`Tracer` is deprecated since version 5.1, directly use "
213 "`IPython.core.debugger.Pdb.set_trace()`",
211 "`IPython.core.debugger.Pdb.set_trace()`",
214 DeprecationWarning, stacklevel=2)
212 DeprecationWarning, stacklevel=2)
215
213
216 ip = get_ipython()
214 ip = get_ipython()
217 if ip is None:
215 if ip is None:
218 # Outside of ipython, we set our own exception hook manually
216 # Outside of ipython, we set our own exception hook manually
219 sys.excepthook = functools.partial(BdbQuit_excepthook,
217 sys.excepthook = functools.partial(BdbQuit_excepthook,
220 excepthook=sys.excepthook)
218 excepthook=sys.excepthook)
221 def_colors = 'NoColor'
219 def_colors = 'NoColor'
222 else:
220 else:
223 # In ipython, we use its custom exception handler mechanism
221 # In ipython, we use its custom exception handler mechanism
224 def_colors = ip.colors
222 def_colors = ip.colors
225 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
223 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
226
224
227 if colors is None:
225 if colors is None:
228 colors = def_colors
226 colors = def_colors
229
227
230 # The stdlib debugger internally uses a modified repr from the `repr`
228 # The stdlib debugger internally uses a modified repr from the `repr`
231 # module, that limits the length of printed strings to a hardcoded
229 # module, that limits the length of printed strings to a hardcoded
232 # limit of 30 characters. That much trimming is too aggressive, let's
230 # limit of 30 characters. That much trimming is too aggressive, let's
233 # at least raise that limit to 80 chars, which should be enough for
231 # at least raise that limit to 80 chars, which should be enough for
234 # most interactive uses.
232 # most interactive uses.
235 try:
233 try:
236 from reprlib import aRepr
234 from reprlib import aRepr
237 aRepr.maxstring = 80
235 aRepr.maxstring = 80
238 except:
236 except:
239 # This is only a user-facing convenience, so any error we encounter
237 # This is only a user-facing convenience, so any error we encounter
240 # here can be warned about but can be otherwise ignored. These
238 # here can be warned about but can be otherwise ignored. These
241 # printouts will tell us about problems if this API changes
239 # printouts will tell us about problems if this API changes
242 import traceback
240 import traceback
243 traceback.print_exc()
241 traceback.print_exc()
244
242
245 self.debugger = Pdb(colors)
243 self.debugger = Pdb(colors)
246
244
247 def __call__(self):
245 def __call__(self):
248 """Starts an interactive debugger at the point where called.
246 """Starts an interactive debugger at the point where called.
249
247
250 This is similar to the pdb.set_trace() function from the std lib, but
248 This is similar to the pdb.set_trace() function from the std lib, but
251 using IPython's enhanced debugger."""
249 using IPython's enhanced debugger."""
252
250
253 self.debugger.set_trace(sys._getframe().f_back)
251 self.debugger.set_trace(sys._getframe().f_back)
254
252
255
253
256 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
254 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
257
255
258
256
259 def strip_indentation(multiline_string):
257 def strip_indentation(multiline_string):
260 return RGX_EXTRA_INDENT.sub('', multiline_string)
258 return RGX_EXTRA_INDENT.sub('', multiline_string)
261
259
262
260
263 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
261 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
264 """Make new_fn have old_fn's doc string. This is particularly useful
262 """Make new_fn have old_fn's doc string. This is particularly useful
265 for the ``do_...`` commands that hook into the help system.
263 for the ``do_...`` commands that hook into the help system.
266 Adapted from from a comp.lang.python posting
264 Adapted from from a comp.lang.python posting
267 by Duncan Booth."""
265 by Duncan Booth."""
268 def wrapper(*args, **kw):
266 def wrapper(*args, **kw):
269 return new_fn(*args, **kw)
267 return new_fn(*args, **kw)
270 if old_fn.__doc__:
268 if old_fn.__doc__:
271 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
269 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
272 return wrapper
270 return wrapper
273
271
274
272
275 class Pdb(OldPdb):
273 class Pdb(OldPdb):
276 """Modified Pdb class, does not load readline.
274 """Modified Pdb class, does not load readline.
277
275
278 for a standalone version that uses prompt_toolkit, see
276 for a standalone version that uses prompt_toolkit, see
279 `IPython.terminal.debugger.TerminalPdb` and
277 `IPython.terminal.debugger.TerminalPdb` and
280 `IPython.terminal.debugger.set_trace()`
278 `IPython.terminal.debugger.set_trace()`
281
279
282
280
283 This debugger can hide and skip frames that are tagged according to some predicates.
281 This debugger can hide and skip frames that are tagged according to some predicates.
284 See the `skip_predicates` commands.
282 See the `skip_predicates` commands.
285
283
286 """
284 """
287
285
288 default_predicates = {
286 default_predicates = {
289 "tbhide": True,
287 "tbhide": True,
290 "readonly": False,
288 "readonly": False,
291 "ipython_internal": True,
289 "ipython_internal": True,
292 "debuggerskip": True,
290 "debuggerskip": True,
293 }
291 }
294
292
295 def __init__(self, color_scheme=None, completekey=None,
293 def __init__(self, color_scheme=None, completekey=None,
296 stdin=None, stdout=None, context=5, **kwargs):
294 stdin=None, stdout=None, context=5, **kwargs):
297 """Create a new IPython debugger.
295 """Create a new IPython debugger.
298
296
299 Parameters
297 Parameters
300 ----------
298 ----------
301 color_scheme : default None
299 color_scheme : default None
302 Deprecated, do not use.
300 Deprecated, do not use.
303 completekey : default None
301 completekey : default None
304 Passed to pdb.Pdb.
302 Passed to pdb.Pdb.
305 stdin : default None
303 stdin : default None
306 Passed to pdb.Pdb.
304 Passed to pdb.Pdb.
307 stdout : default None
305 stdout : default None
308 Passed to pdb.Pdb.
306 Passed to pdb.Pdb.
309 context : int
307 context : int
310 Number of lines of source code context to show when
308 Number of lines of source code context to show when
311 displaying stacktrace information.
309 displaying stacktrace information.
312 **kwargs
310 **kwargs
313 Passed to pdb.Pdb.
311 Passed to pdb.Pdb.
314
312
315 Notes
313 Notes
316 -----
314 -----
317 The possibilities are python version dependent, see the python
315 The possibilities are python version dependent, see the python
318 docs for more info.
316 docs for more info.
319 """
317 """
320
318
321 # Parent constructor:
319 # Parent constructor:
322 try:
320 try:
323 self.context = int(context)
321 self.context = int(context)
324 if self.context <= 0:
322 if self.context <= 0:
325 raise ValueError("Context must be a positive integer")
323 raise ValueError("Context must be a positive integer")
326 except (TypeError, ValueError) as e:
324 except (TypeError, ValueError) as e:
327 raise ValueError("Context must be a positive integer") from e
325 raise ValueError("Context must be a positive integer") from e
328
326
329 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
327 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
330 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
328 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
331
329
332 # IPython changes...
330 # IPython changes...
333 self.shell = get_ipython()
331 self.shell = get_ipython()
334
332
335 if self.shell is None:
333 if self.shell is None:
336 save_main = sys.modules['__main__']
334 save_main = sys.modules['__main__']
337 # No IPython instance running, we must create one
335 # No IPython instance running, we must create one
338 from IPython.terminal.interactiveshell import \
336 from IPython.terminal.interactiveshell import \
339 TerminalInteractiveShell
337 TerminalInteractiveShell
340 self.shell = TerminalInteractiveShell.instance()
338 self.shell = TerminalInteractiveShell.instance()
341 # needed by any code which calls __import__("__main__") after
339 # needed by any code which calls __import__("__main__") after
342 # the debugger was entered. See also #9941.
340 # the debugger was entered. See also #9941.
343 sys.modules["__main__"] = save_main
341 sys.modules["__main__"] = save_main
344
342
345 if color_scheme is not None:
343 if color_scheme is not None:
346 warnings.warn(
344 warnings.warn(
347 "The `color_scheme` argument is deprecated since version 5.1",
345 "The `color_scheme` argument is deprecated since version 5.1",
348 DeprecationWarning, stacklevel=2)
346 DeprecationWarning, stacklevel=2)
349 else:
347 else:
350 color_scheme = self.shell.colors
348 color_scheme = self.shell.colors
351
349
352 self.aliases = {}
350 self.aliases = {}
353
351
354 # Create color table: we copy the default one from the traceback
352 # Create color table: we copy the default one from the traceback
355 # module and add a few attributes needed for debugging
353 # module and add a few attributes needed for debugging
356 self.color_scheme_table = exception_colors()
354 self.color_scheme_table = exception_colors()
357
355
358 # shorthands
356 # shorthands
359 C = coloransi.TermColors
357 C = coloransi.TermColors
360 cst = self.color_scheme_table
358 cst = self.color_scheme_table
361
359
362 cst['NoColor'].colors.prompt = C.NoColor
360 cst['NoColor'].colors.prompt = C.NoColor
363 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
361 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
364 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
362 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
365
363
366 cst['Linux'].colors.prompt = C.Green
364 cst['Linux'].colors.prompt = C.Green
367 cst['Linux'].colors.breakpoint_enabled = C.LightRed
365 cst['Linux'].colors.breakpoint_enabled = C.LightRed
368 cst['Linux'].colors.breakpoint_disabled = C.Red
366 cst['Linux'].colors.breakpoint_disabled = C.Red
369
367
370 cst['LightBG'].colors.prompt = C.Blue
368 cst['LightBG'].colors.prompt = C.Blue
371 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
369 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
372 cst['LightBG'].colors.breakpoint_disabled = C.Red
370 cst['LightBG'].colors.breakpoint_disabled = C.Red
373
371
374 cst['Neutral'].colors.prompt = C.Blue
372 cst['Neutral'].colors.prompt = C.Blue
375 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
373 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
376 cst['Neutral'].colors.breakpoint_disabled = C.Red
374 cst['Neutral'].colors.breakpoint_disabled = C.Red
377
375
378 # Add a python parser so we can syntax highlight source while
376 # Add a python parser so we can syntax highlight source while
379 # debugging.
377 # debugging.
380 self.parser = PyColorize.Parser(style=color_scheme)
378 self.parser = PyColorize.Parser(style=color_scheme)
381 self.set_colors(color_scheme)
379 self.set_colors(color_scheme)
382
380
383 # Set the prompt - the default prompt is '(Pdb)'
381 # Set the prompt - the default prompt is '(Pdb)'
384 self.prompt = prompt
382 self.prompt = prompt
385 self.skip_hidden = True
383 self.skip_hidden = True
386 self.report_skipped = True
384 self.report_skipped = True
387
385
388 # list of predicates we use to skip frames
386 # list of predicates we use to skip frames
389 self._predicates = self.default_predicates
387 self._predicates = self.default_predicates
390
388
391 #
389 #
392 def set_colors(self, scheme):
390 def set_colors(self, scheme):
393 """Shorthand access to the color table scheme selector method."""
391 """Shorthand access to the color table scheme selector method."""
394 self.color_scheme_table.set_active_scheme(scheme)
392 self.color_scheme_table.set_active_scheme(scheme)
395 self.parser.style = scheme
393 self.parser.style = scheme
396
394
397 def set_trace(self, frame=None):
395 def set_trace(self, frame=None):
398 if frame is None:
396 if frame is None:
399 frame = sys._getframe().f_back
397 frame = sys._getframe().f_back
400 self.initial_frame = frame
398 self.initial_frame = frame
401 return super().set_trace(frame)
399 return super().set_trace(frame)
402
400
403 def _hidden_predicate(self, frame):
401 def _hidden_predicate(self, frame):
404 """
402 """
405 Given a frame return whether it it should be hidden or not by IPython.
403 Given a frame return whether it it should be hidden or not by IPython.
406 """
404 """
407
405
408 if self._predicates["readonly"]:
406 if self._predicates["readonly"]:
409 fname = frame.f_code.co_filename
407 fname = frame.f_code.co_filename
410 # we need to check for file existence and interactively define
408 # we need to check for file existence and interactively define
411 # function would otherwise appear as RO.
409 # function would otherwise appear as RO.
412 if os.path.isfile(fname) and not os.access(fname, os.W_OK):
410 if os.path.isfile(fname) and not os.access(fname, os.W_OK):
413 return True
411 return True
414
412
415 if self._predicates["tbhide"]:
413 if self._predicates["tbhide"]:
416 if frame in (self.curframe, getattr(self, "initial_frame", None)):
414 if frame in (self.curframe, getattr(self, "initial_frame", None)):
417 return False
415 return False
418 frame_locals = self._get_frame_locals(frame)
416 frame_locals = self._get_frame_locals(frame)
419 if "__tracebackhide__" not in frame_locals:
417 if "__tracebackhide__" not in frame_locals:
420 return False
418 return False
421 return frame_locals["__tracebackhide__"]
419 return frame_locals["__tracebackhide__"]
422 return False
420 return False
423
421
424 def hidden_frames(self, stack):
422 def hidden_frames(self, stack):
425 """
423 """
426 Given an index in the stack return whether it should be skipped.
424 Given an index in the stack return whether it should be skipped.
427
425
428 This is used in up/down and where to skip frames.
426 This is used in up/down and where to skip frames.
429 """
427 """
430 # The f_locals dictionary is updated from the actual frame
428 # The f_locals dictionary is updated from the actual frame
431 # locals whenever the .f_locals accessor is called, so we
429 # locals whenever the .f_locals accessor is called, so we
432 # avoid calling it here to preserve self.curframe_locals.
430 # avoid calling it here to preserve self.curframe_locals.
433 # Furthermore, there is no good reason to hide the current frame.
431 # Furthermore, there is no good reason to hide the current frame.
434 ip_hide = [self._hidden_predicate(s[0]) for s in stack]
432 ip_hide = [self._hidden_predicate(s[0]) for s in stack]
435 ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"]
433 ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"]
436 if ip_start and self._predicates["ipython_internal"]:
434 if ip_start and self._predicates["ipython_internal"]:
437 ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)]
435 ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)]
438 return ip_hide
436 return ip_hide
439
437
440 def interaction(self, frame, traceback):
438 def interaction(self, frame, traceback):
441 try:
439 try:
442 OldPdb.interaction(self, frame, traceback)
440 OldPdb.interaction(self, frame, traceback)
443 except KeyboardInterrupt:
441 except KeyboardInterrupt:
444 self.stdout.write("\n" + self.shell.get_exception_only())
442 self.stdout.write("\n" + self.shell.get_exception_only())
445
443
446 def precmd(self, line):
444 def precmd(self, line):
447 """Perform useful escapes on the command before it is executed."""
445 """Perform useful escapes on the command before it is executed."""
448
446
449 if line.endswith("??"):
447 if line.endswith("??"):
450 line = "pinfo2 " + line[:-2]
448 line = "pinfo2 " + line[:-2]
451 elif line.endswith("?"):
449 elif line.endswith("?"):
452 line = "pinfo " + line[:-1]
450 line = "pinfo " + line[:-1]
453
451
454 line = super().precmd(line)
452 line = super().precmd(line)
455
453
456 return line
454 return line
457
455
458 def new_do_frame(self, arg):
456 def new_do_frame(self, arg):
459 OldPdb.do_frame(self, arg)
457 OldPdb.do_frame(self, arg)
460
458
461 def new_do_quit(self, arg):
459 def new_do_quit(self, arg):
462
460
463 if hasattr(self, 'old_all_completions'):
461 if hasattr(self, 'old_all_completions'):
464 self.shell.Completer.all_completions = self.old_all_completions
462 self.shell.Completer.all_completions = self.old_all_completions
465
463
466 return OldPdb.do_quit(self, arg)
464 return OldPdb.do_quit(self, arg)
467
465
468 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
466 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
469
467
470 def new_do_restart(self, arg):
468 def new_do_restart(self, arg):
471 """Restart command. In the context of ipython this is exactly the same
469 """Restart command. In the context of ipython this is exactly the same
472 thing as 'quit'."""
470 thing as 'quit'."""
473 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
471 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
474 return self.do_quit(arg)
472 return self.do_quit(arg)
475
473
476 def print_stack_trace(self, context=None):
474 def print_stack_trace(self, context=None):
477 Colors = self.color_scheme_table.active_colors
475 Colors = self.color_scheme_table.active_colors
478 ColorsNormal = Colors.Normal
476 ColorsNormal = Colors.Normal
479 if context is None:
477 if context is None:
480 context = self.context
478 context = self.context
481 try:
479 try:
482 context = int(context)
480 context = int(context)
483 if context <= 0:
481 if context <= 0:
484 raise ValueError("Context must be a positive integer")
482 raise ValueError("Context must be a positive integer")
485 except (TypeError, ValueError) as e:
483 except (TypeError, ValueError) as e:
486 raise ValueError("Context must be a positive integer") from e
484 raise ValueError("Context must be a positive integer") from e
487 try:
485 try:
488 skipped = 0
486 skipped = 0
489 for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack):
487 for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack):
490 if hidden and self.skip_hidden:
488 if hidden and self.skip_hidden:
491 skipped += 1
489 skipped += 1
492 continue
490 continue
493 if skipped:
491 if skipped:
494 print(
492 print(
495 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
493 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
496 )
494 )
497 skipped = 0
495 skipped = 0
498 self.print_stack_entry(frame_lineno, context=context)
496 self.print_stack_entry(frame_lineno, context=context)
499 if skipped:
497 if skipped:
500 print(
498 print(
501 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
499 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
502 )
500 )
503 except KeyboardInterrupt:
501 except KeyboardInterrupt:
504 pass
502 pass
505
503
506 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
504 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
507 context=None):
505 context=None):
508 if context is None:
506 if context is None:
509 context = self.context
507 context = self.context
510 try:
508 try:
511 context = int(context)
509 context = int(context)
512 if context <= 0:
510 if context <= 0:
513 raise ValueError("Context must be a positive integer")
511 raise ValueError("Context must be a positive integer")
514 except (TypeError, ValueError) as e:
512 except (TypeError, ValueError) as e:
515 raise ValueError("Context must be a positive integer") from e
513 raise ValueError("Context must be a positive integer") from e
516 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
514 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
517
515
518 # vds: >>
516 # vds: >>
519 frame, lineno = frame_lineno
517 frame, lineno = frame_lineno
520 filename = frame.f_code.co_filename
518 filename = frame.f_code.co_filename
521 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
519 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
522 # vds: <<
520 # vds: <<
523
521
524 def _get_frame_locals(self, frame):
522 def _get_frame_locals(self, frame):
525 """ "
523 """ "
526 Accessing f_local of current frame reset the namespace, so we want to avoid
524 Accessing f_local of current frame reset the namespace, so we want to avoid
527 that or the following can happen
525 that or the following can happen
528
526
529 ipdb> foo
527 ipdb> foo
530 "old"
528 "old"
531 ipdb> foo = "new"
529 ipdb> foo = "new"
532 ipdb> foo
530 ipdb> foo
533 "new"
531 "new"
534 ipdb> where
532 ipdb> where
535 ipdb> foo
533 ipdb> foo
536 "old"
534 "old"
537
535
538 So if frame is self.current_frame we instead return self.curframe_locals
536 So if frame is self.current_frame we instead return self.curframe_locals
539
537
540 """
538 """
541 if frame is self.curframe:
539 if frame is self.curframe:
542 return self.curframe_locals
540 return self.curframe_locals
543 else:
541 else:
544 return frame.f_locals
542 return frame.f_locals
545
543
546 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
544 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
547 if context is None:
545 if context is None:
548 context = self.context
546 context = self.context
549 try:
547 try:
550 context = int(context)
548 context = int(context)
551 if context <= 0:
549 if context <= 0:
552 print("Context must be a positive integer", file=self.stdout)
550 print("Context must be a positive integer", file=self.stdout)
553 except (TypeError, ValueError):
551 except (TypeError, ValueError):
554 print("Context must be a positive integer", file=self.stdout)
552 print("Context must be a positive integer", file=self.stdout)
555
553
556 import reprlib
554 import reprlib
557
555
558 ret = []
556 ret = []
559
557
560 Colors = self.color_scheme_table.active_colors
558 Colors = self.color_scheme_table.active_colors
561 ColorsNormal = Colors.Normal
559 ColorsNormal = Colors.Normal
562 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
560 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
563 tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
561 tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
564 tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
562 tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
565 tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
563 tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
566
564
567 frame, lineno = frame_lineno
565 frame, lineno = frame_lineno
568
566
569 return_value = ''
567 return_value = ''
570 loc_frame = self._get_frame_locals(frame)
568 loc_frame = self._get_frame_locals(frame)
571 if "__return__" in loc_frame:
569 if "__return__" in loc_frame:
572 rv = loc_frame["__return__"]
570 rv = loc_frame["__return__"]
573 # return_value += '->'
571 # return_value += '->'
574 return_value += reprlib.repr(rv) + "\n"
572 return_value += reprlib.repr(rv) + "\n"
575 ret.append(return_value)
573 ret.append(return_value)
576
574
577 #s = filename + '(' + `lineno` + ')'
575 #s = filename + '(' + `lineno` + ')'
578 filename = self.canonic(frame.f_code.co_filename)
576 filename = self.canonic(frame.f_code.co_filename)
579 link = tpl_link % py3compat.cast_unicode(filename)
577 link = tpl_link % py3compat.cast_unicode(filename)
580
578
581 if frame.f_code.co_name:
579 if frame.f_code.co_name:
582 func = frame.f_code.co_name
580 func = frame.f_code.co_name
583 else:
581 else:
584 func = "<lambda>"
582 func = "<lambda>"
585
583
586 call = ""
584 call = ""
587 if func != "?":
585 if func != "?":
588 if "__args__" in loc_frame:
586 if "__args__" in loc_frame:
589 args = reprlib.repr(loc_frame["__args__"])
587 args = reprlib.repr(loc_frame["__args__"])
590 else:
588 else:
591 args = '()'
589 args = '()'
592 call = tpl_call % (func, args)
590 call = tpl_call % (func, args)
593
591
594 # The level info should be generated in the same format pdb uses, to
592 # The level info should be generated in the same format pdb uses, to
595 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
593 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
596 if frame is self.curframe:
594 if frame is self.curframe:
597 ret.append('> ')
595 ret.append('> ')
598 else:
596 else:
599 ret.append(" ")
597 ret.append(" ")
600 ret.append("%s(%s)%s\n" % (link, lineno, call))
598 ret.append("%s(%s)%s\n" % (link, lineno, call))
601
599
602 start = lineno - 1 - context//2
600 start = lineno - 1 - context//2
603 lines = linecache.getlines(filename)
601 lines = linecache.getlines(filename)
604 start = min(start, len(lines) - context)
602 start = min(start, len(lines) - context)
605 start = max(start, 0)
603 start = max(start, 0)
606 lines = lines[start : start + context]
604 lines = lines[start : start + context]
607
605
608 for i, line in enumerate(lines):
606 for i, line in enumerate(lines):
609 show_arrow = start + 1 + i == lineno
607 show_arrow = start + 1 + i == lineno
610 linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
608 linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
611 ret.append(
609 ret.append(
612 self.__format_line(
610 self.__format_line(
613 linetpl, filename, start + 1 + i, line, arrow=show_arrow
611 linetpl, filename, start + 1 + i, line, arrow=show_arrow
614 )
612 )
615 )
613 )
616 return "".join(ret)
614 return "".join(ret)
617
615
618 def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
616 def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
619 bp_mark = ""
617 bp_mark = ""
620 bp_mark_color = ""
618 bp_mark_color = ""
621
619
622 new_line, err = self.parser.format2(line, 'str')
620 new_line, err = self.parser.format2(line, 'str')
623 if not err:
621 if not err:
624 line = new_line
622 line = new_line
625
623
626 bp = None
624 bp = None
627 if lineno in self.get_file_breaks(filename):
625 if lineno in self.get_file_breaks(filename):
628 bps = self.get_breaks(filename, lineno)
626 bps = self.get_breaks(filename, lineno)
629 bp = bps[-1]
627 bp = bps[-1]
630
628
631 if bp:
629 if bp:
632 Colors = self.color_scheme_table.active_colors
630 Colors = self.color_scheme_table.active_colors
633 bp_mark = str(bp.number)
631 bp_mark = str(bp.number)
634 bp_mark_color = Colors.breakpoint_enabled
632 bp_mark_color = Colors.breakpoint_enabled
635 if not bp.enabled:
633 if not bp.enabled:
636 bp_mark_color = Colors.breakpoint_disabled
634 bp_mark_color = Colors.breakpoint_disabled
637
635
638 numbers_width = 7
636 numbers_width = 7
639 if arrow:
637 if arrow:
640 # This is the line with the error
638 # This is the line with the error
641 pad = numbers_width - len(str(lineno)) - len(bp_mark)
639 pad = numbers_width - len(str(lineno)) - len(bp_mark)
642 num = '%s%s' % (make_arrow(pad), str(lineno))
640 num = '%s%s' % (make_arrow(pad), str(lineno))
643 else:
641 else:
644 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
642 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
645
643
646 return tpl_line % (bp_mark_color + bp_mark, num, line)
644 return tpl_line % (bp_mark_color + bp_mark, num, line)
647
645
648 def print_list_lines(self, filename, first, last):
646 def print_list_lines(self, filename, first, last):
649 """The printing (as opposed to the parsing part of a 'list'
647 """The printing (as opposed to the parsing part of a 'list'
650 command."""
648 command."""
651 try:
649 try:
652 Colors = self.color_scheme_table.active_colors
650 Colors = self.color_scheme_table.active_colors
653 ColorsNormal = Colors.Normal
651 ColorsNormal = Colors.Normal
654 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
652 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
655 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
653 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
656 src = []
654 src = []
657 if filename == "<string>" and hasattr(self, "_exec_filename"):
655 if filename == "<string>" and hasattr(self, "_exec_filename"):
658 filename = self._exec_filename
656 filename = self._exec_filename
659
657
660 for lineno in range(first, last+1):
658 for lineno in range(first, last+1):
661 line = linecache.getline(filename, lineno)
659 line = linecache.getline(filename, lineno)
662 if not line:
660 if not line:
663 break
661 break
664
662
665 if lineno == self.curframe.f_lineno:
663 if lineno == self.curframe.f_lineno:
666 line = self.__format_line(
664 line = self.__format_line(
667 tpl_line_em, filename, lineno, line, arrow=True
665 tpl_line_em, filename, lineno, line, arrow=True
668 )
666 )
669 else:
667 else:
670 line = self.__format_line(
668 line = self.__format_line(
671 tpl_line, filename, lineno, line, arrow=False
669 tpl_line, filename, lineno, line, arrow=False
672 )
670 )
673
671
674 src.append(line)
672 src.append(line)
675 self.lineno = lineno
673 self.lineno = lineno
676
674
677 print(''.join(src), file=self.stdout)
675 print(''.join(src), file=self.stdout)
678
676
679 except KeyboardInterrupt:
677 except KeyboardInterrupt:
680 pass
678 pass
681
679
682 def do_skip_predicates(self, args):
680 def do_skip_predicates(self, args):
683 """
681 """
684 Turn on/off individual predicates as to whether a frame should be hidden/skip.
682 Turn on/off individual predicates as to whether a frame should be hidden/skip.
685
683
686 The global option to skip (or not) hidden frames is set with skip_hidden
684 The global option to skip (or not) hidden frames is set with skip_hidden
687
685
688 To change the value of a predicate
686 To change the value of a predicate
689
687
690 skip_predicates key [true|false]
688 skip_predicates key [true|false]
691
689
692 Call without arguments to see the current values.
690 Call without arguments to see the current values.
693
691
694 To permanently change the value of an option add the corresponding
692 To permanently change the value of an option add the corresponding
695 command to your ``~/.pdbrc`` file. If you are programmatically using the
693 command to your ``~/.pdbrc`` file. If you are programmatically using the
696 Pdb instance you can also change the ``default_predicates`` class
694 Pdb instance you can also change the ``default_predicates`` class
697 attribute.
695 attribute.
698 """
696 """
699 if not args.strip():
697 if not args.strip():
700 print("current predicates:")
698 print("current predicates:")
701 for (p, v) in self._predicates.items():
699 for (p, v) in self._predicates.items():
702 print(" ", p, ":", v)
700 print(" ", p, ":", v)
703 return
701 return
704 type_value = args.strip().split(" ")
702 type_value = args.strip().split(" ")
705 if len(type_value) != 2:
703 if len(type_value) != 2:
706 print(
704 print(
707 f"Usage: skip_predicates <type> <value>, with <type> one of {set(self._predicates.keys())}"
705 f"Usage: skip_predicates <type> <value>, with <type> one of {set(self._predicates.keys())}"
708 )
706 )
709 return
707 return
710
708
711 type_, value = type_value
709 type_, value = type_value
712 if type_ not in self._predicates:
710 if type_ not in self._predicates:
713 print(f"{type_!r} not in {set(self._predicates.keys())}")
711 print(f"{type_!r} not in {set(self._predicates.keys())}")
714 return
712 return
715 if value.lower() not in ("true", "yes", "1", "no", "false", "0"):
713 if value.lower() not in ("true", "yes", "1", "no", "false", "0"):
716 print(
714 print(
717 f"{value!r} is invalid - use one of ('true', 'yes', '1', 'no', 'false', '0')"
715 f"{value!r} is invalid - use one of ('true', 'yes', '1', 'no', 'false', '0')"
718 )
716 )
719 return
717 return
720
718
721 self._predicates[type_] = value.lower() in ("true", "yes", "1")
719 self._predicates[type_] = value.lower() in ("true", "yes", "1")
722 if not any(self._predicates.values()):
720 if not any(self._predicates.values()):
723 print(
721 print(
724 "Warning, all predicates set to False, skip_hidden may not have any effects."
722 "Warning, all predicates set to False, skip_hidden may not have any effects."
725 )
723 )
726
724
727 def do_skip_hidden(self, arg):
725 def do_skip_hidden(self, arg):
728 """
726 """
729 Change whether or not we should skip frames with the
727 Change whether or not we should skip frames with the
730 __tracebackhide__ attribute.
728 __tracebackhide__ attribute.
731 """
729 """
732 if not arg.strip():
730 if not arg.strip():
733 print(
731 print(
734 f"skip_hidden = {self.skip_hidden}, use 'yes','no', 'true', or 'false' to change."
732 f"skip_hidden = {self.skip_hidden}, use 'yes','no', 'true', or 'false' to change."
735 )
733 )
736 elif arg.strip().lower() in ("true", "yes"):
734 elif arg.strip().lower() in ("true", "yes"):
737 self.skip_hidden = True
735 self.skip_hidden = True
738 elif arg.strip().lower() in ("false", "no"):
736 elif arg.strip().lower() in ("false", "no"):
739 self.skip_hidden = False
737 self.skip_hidden = False
740 if not any(self._predicates.values()):
738 if not any(self._predicates.values()):
741 print(
739 print(
742 "Warning, all predicates set to False, skip_hidden may not have any effects."
740 "Warning, all predicates set to False, skip_hidden may not have any effects."
743 )
741 )
744
742
745 def do_list(self, arg):
743 def do_list(self, arg):
746 """Print lines of code from the current stack frame
744 """Print lines of code from the current stack frame
747 """
745 """
748 self.lastcmd = 'list'
746 self.lastcmd = 'list'
749 last = None
747 last = None
750 if arg:
748 if arg:
751 try:
749 try:
752 x = eval(arg, {}, {})
750 x = eval(arg, {}, {})
753 if type(x) == type(()):
751 if type(x) == type(()):
754 first, last = x
752 first, last = x
755 first = int(first)
753 first = int(first)
756 last = int(last)
754 last = int(last)
757 if last < first:
755 if last < first:
758 # Assume it's a count
756 # Assume it's a count
759 last = first + last
757 last = first + last
760 else:
758 else:
761 first = max(1, int(x) - 5)
759 first = max(1, int(x) - 5)
762 except:
760 except:
763 print('*** Error in argument:', repr(arg), file=self.stdout)
761 print('*** Error in argument:', repr(arg), file=self.stdout)
764 return
762 return
765 elif self.lineno is None:
763 elif self.lineno is None:
766 first = max(1, self.curframe.f_lineno - 5)
764 first = max(1, self.curframe.f_lineno - 5)
767 else:
765 else:
768 first = self.lineno + 1
766 first = self.lineno + 1
769 if last is None:
767 if last is None:
770 last = first + 10
768 last = first + 10
771 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
769 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
772
770
773 # vds: >>
771 # vds: >>
774 lineno = first
772 lineno = first
775 filename = self.curframe.f_code.co_filename
773 filename = self.curframe.f_code.co_filename
776 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
774 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
777 # vds: <<
775 # vds: <<
778
776
779 do_l = do_list
777 do_l = do_list
780
778
781 def getsourcelines(self, obj):
779 def getsourcelines(self, obj):
782 lines, lineno = inspect.findsource(obj)
780 lines, lineno = inspect.findsource(obj)
783 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
781 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
784 # must be a module frame: do not try to cut a block out of it
782 # must be a module frame: do not try to cut a block out of it
785 return lines, 1
783 return lines, 1
786 elif inspect.ismodule(obj):
784 elif inspect.ismodule(obj):
787 return lines, 1
785 return lines, 1
788 return inspect.getblock(lines[lineno:]), lineno+1
786 return inspect.getblock(lines[lineno:]), lineno+1
789
787
790 def do_longlist(self, arg):
788 def do_longlist(self, arg):
791 """Print lines of code from the current stack frame.
789 """Print lines of code from the current stack frame.
792
790
793 Shows more lines than 'list' does.
791 Shows more lines than 'list' does.
794 """
792 """
795 self.lastcmd = 'longlist'
793 self.lastcmd = 'longlist'
796 try:
794 try:
797 lines, lineno = self.getsourcelines(self.curframe)
795 lines, lineno = self.getsourcelines(self.curframe)
798 except OSError as err:
796 except OSError as err:
799 self.error(err)
797 self.error(err)
800 return
798 return
801 last = lineno + len(lines)
799 last = lineno + len(lines)
802 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
800 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
803 do_ll = do_longlist
801 do_ll = do_longlist
804
802
805 def do_debug(self, arg):
803 def do_debug(self, arg):
806 """debug code
804 """debug code
807 Enter a recursive debugger that steps through the code
805 Enter a recursive debugger that steps through the code
808 argument (which is an arbitrary expression or statement to be
806 argument (which is an arbitrary expression or statement to be
809 executed in the current environment).
807 executed in the current environment).
810 """
808 """
811 trace_function = sys.gettrace()
809 trace_function = sys.gettrace()
812 sys.settrace(None)
810 sys.settrace(None)
813 globals = self.curframe.f_globals
811 globals = self.curframe.f_globals
814 locals = self.curframe_locals
812 locals = self.curframe_locals
815 p = self.__class__(completekey=self.completekey,
813 p = self.__class__(completekey=self.completekey,
816 stdin=self.stdin, stdout=self.stdout)
814 stdin=self.stdin, stdout=self.stdout)
817 p.use_rawinput = self.use_rawinput
815 p.use_rawinput = self.use_rawinput
818 p.prompt = "(%s) " % self.prompt.strip()
816 p.prompt = "(%s) " % self.prompt.strip()
819 self.message("ENTERING RECURSIVE DEBUGGER")
817 self.message("ENTERING RECURSIVE DEBUGGER")
820 sys.call_tracing(p.run, (arg, globals, locals))
818 sys.call_tracing(p.run, (arg, globals, locals))
821 self.message("LEAVING RECURSIVE DEBUGGER")
819 self.message("LEAVING RECURSIVE DEBUGGER")
822 sys.settrace(trace_function)
820 sys.settrace(trace_function)
823 self.lastcmd = p.lastcmd
821 self.lastcmd = p.lastcmd
824
822
825 def do_pdef(self, arg):
823 def do_pdef(self, arg):
826 """Print the call signature for any callable object.
824 """Print the call signature for any callable object.
827
825
828 The debugger interface to %pdef"""
826 The debugger interface to %pdef"""
829 namespaces = [
827 namespaces = [
830 ("Locals", self.curframe_locals),
828 ("Locals", self.curframe_locals),
831 ("Globals", self.curframe.f_globals),
829 ("Globals", self.curframe.f_globals),
832 ]
830 ]
833 self.shell.find_line_magic("pdef")(arg, namespaces=namespaces)
831 self.shell.find_line_magic("pdef")(arg, namespaces=namespaces)
834
832
835 def do_pdoc(self, arg):
833 def do_pdoc(self, arg):
836 """Print the docstring for an object.
834 """Print the docstring for an object.
837
835
838 The debugger interface to %pdoc."""
836 The debugger interface to %pdoc."""
839 namespaces = [
837 namespaces = [
840 ("Locals", self.curframe_locals),
838 ("Locals", self.curframe_locals),
841 ("Globals", self.curframe.f_globals),
839 ("Globals", self.curframe.f_globals),
842 ]
840 ]
843 self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces)
841 self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces)
844
842
845 def do_pfile(self, arg):
843 def do_pfile(self, arg):
846 """Print (or run through pager) the file where an object is defined.
844 """Print (or run through pager) the file where an object is defined.
847
845
848 The debugger interface to %pfile.
846 The debugger interface to %pfile.
849 """
847 """
850 namespaces = [
848 namespaces = [
851 ("Locals", self.curframe_locals),
849 ("Locals", self.curframe_locals),
852 ("Globals", self.curframe.f_globals),
850 ("Globals", self.curframe.f_globals),
853 ]
851 ]
854 self.shell.find_line_magic("pfile")(arg, namespaces=namespaces)
852 self.shell.find_line_magic("pfile")(arg, namespaces=namespaces)
855
853
856 def do_pinfo(self, arg):
854 def do_pinfo(self, arg):
857 """Provide detailed information about an object.
855 """Provide detailed information about an object.
858
856
859 The debugger interface to %pinfo, i.e., obj?."""
857 The debugger interface to %pinfo, i.e., obj?."""
860 namespaces = [
858 namespaces = [
861 ("Locals", self.curframe_locals),
859 ("Locals", self.curframe_locals),
862 ("Globals", self.curframe.f_globals),
860 ("Globals", self.curframe.f_globals),
863 ]
861 ]
864 self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces)
862 self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces)
865
863
866 def do_pinfo2(self, arg):
864 def do_pinfo2(self, arg):
867 """Provide extra detailed information about an object.
865 """Provide extra detailed information about an object.
868
866
869 The debugger interface to %pinfo2, i.e., obj??."""
867 The debugger interface to %pinfo2, i.e., obj??."""
870 namespaces = [
868 namespaces = [
871 ("Locals", self.curframe_locals),
869 ("Locals", self.curframe_locals),
872 ("Globals", self.curframe.f_globals),
870 ("Globals", self.curframe.f_globals),
873 ]
871 ]
874 self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces)
872 self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces)
875
873
876 def do_psource(self, arg):
874 def do_psource(self, arg):
877 """Print (or run through pager) the source code for an object."""
875 """Print (or run through pager) the source code for an object."""
878 namespaces = [
876 namespaces = [
879 ("Locals", self.curframe_locals),
877 ("Locals", self.curframe_locals),
880 ("Globals", self.curframe.f_globals),
878 ("Globals", self.curframe.f_globals),
881 ]
879 ]
882 self.shell.find_line_magic("psource")(arg, namespaces=namespaces)
880 self.shell.find_line_magic("psource")(arg, namespaces=namespaces)
883
881
884 def do_where(self, arg):
882 def do_where(self, arg):
885 """w(here)
883 """w(here)
886 Print a stack trace, with the most recent frame at the bottom.
884 Print a stack trace, with the most recent frame at the bottom.
887 An arrow indicates the "current frame", which determines the
885 An arrow indicates the "current frame", which determines the
888 context of most commands. 'bt' is an alias for this command.
886 context of most commands. 'bt' is an alias for this command.
889
887
890 Take a number as argument as an (optional) number of context line to
888 Take a number as argument as an (optional) number of context line to
891 print"""
889 print"""
892 if arg:
890 if arg:
893 try:
891 try:
894 context = int(arg)
892 context = int(arg)
895 except ValueError as err:
893 except ValueError as err:
896 self.error(err)
894 self.error(err)
897 return
895 return
898 self.print_stack_trace(context)
896 self.print_stack_trace(context)
899 else:
897 else:
900 self.print_stack_trace()
898 self.print_stack_trace()
901
899
902 do_w = do_where
900 do_w = do_where
903
901
904 def break_anywhere(self, frame):
902 def break_anywhere(self, frame):
905 """
903 """
906
904
907 _stop_in_decorator_internals is overly restrictive, as we may still want
905 _stop_in_decorator_internals is overly restrictive, as we may still want
908 to trace function calls, so we need to also update break_anywhere so
906 to trace function calls, so we need to also update break_anywhere so
909 that is we don't `stop_here`, because of debugger skip, we may still
907 that is we don't `stop_here`, because of debugger skip, we may still
910 stop at any point inside the function
908 stop at any point inside the function
911
909
912 """
910 """
913
911
914 sup = super().break_anywhere(frame)
912 sup = super().break_anywhere(frame)
915 if sup:
913 if sup:
916 return sup
914 return sup
917 if self._predicates["debuggerskip"]:
915 if self._predicates["debuggerskip"]:
918 if DEBUGGERSKIP in frame.f_code.co_varnames:
916 if DEBUGGERSKIP in frame.f_code.co_varnames:
919 return True
917 return True
920 if frame.f_back and self._get_frame_locals(frame.f_back).get(DEBUGGERSKIP):
918 if frame.f_back and self._get_frame_locals(frame.f_back).get(DEBUGGERSKIP):
921 return True
919 return True
922 return False
920 return False
923
921
924 @skip_doctest
925 def _is_in_decorator_internal_and_should_skip(self, frame):
922 def _is_in_decorator_internal_and_should_skip(self, frame):
926 """
923 """
927 Utility to tell us whether we are in a decorator internal and should stop.
924 Utility to tell us whether we are in a decorator internal and should stop.
928
925
929
926
930
927
931 """
928 """
932
929
933 # if we are disabled don't skip
930 # if we are disabled don't skip
934 if not self._predicates["debuggerskip"]:
931 if not self._predicates["debuggerskip"]:
935 return False
932 return False
936
933
937 # if frame is tagged, skip by default.
934 # if frame is tagged, skip by default.
938 if DEBUGGERSKIP in frame.f_code.co_varnames:
935 if DEBUGGERSKIP in frame.f_code.co_varnames:
939 return True
936 return True
940
937
941 # if one of the parent frame value set to True skip as well.
938 # if one of the parent frame value set to True skip as well.
942
939
943 cframe = frame
940 cframe = frame
944 while getattr(cframe, "f_back", None):
941 while getattr(cframe, "f_back", None):
945 cframe = cframe.f_back
942 cframe = cframe.f_back
946 if self._get_frame_locals(cframe).get(DEBUGGERSKIP):
943 if self._get_frame_locals(cframe).get(DEBUGGERSKIP):
947 return True
944 return True
948
945
949 return False
946 return False
950
947
951 def stop_here(self, frame):
948 def stop_here(self, frame):
952
949
953 if self._is_in_decorator_internal_and_should_skip(frame) is True:
950 if self._is_in_decorator_internal_and_should_skip(frame) is True:
954 return False
951 return False
955
952
956 hidden = False
953 hidden = False
957 if self.skip_hidden:
954 if self.skip_hidden:
958 hidden = self._hidden_predicate(frame)
955 hidden = self._hidden_predicate(frame)
959 if hidden:
956 if hidden:
960 if self.report_skipped:
957 if self.report_skipped:
961 Colors = self.color_scheme_table.active_colors
958 Colors = self.color_scheme_table.active_colors
962 ColorsNormal = Colors.Normal
959 ColorsNormal = Colors.Normal
963 print(
960 print(
964 f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n"
961 f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n"
965 )
962 )
966 return super().stop_here(frame)
963 return super().stop_here(frame)
967
964
968 def do_up(self, arg):
965 def do_up(self, arg):
969 """u(p) [count]
966 """u(p) [count]
970 Move the current frame count (default one) levels up in the
967 Move the current frame count (default one) levels up in the
971 stack trace (to an older frame).
968 stack trace (to an older frame).
972
969
973 Will skip hidden frames.
970 Will skip hidden frames.
974 """
971 """
975 # modified version of upstream that skips
972 # modified version of upstream that skips
976 # frames with __tracebackhide__
973 # frames with __tracebackhide__
977 if self.curindex == 0:
974 if self.curindex == 0:
978 self.error("Oldest frame")
975 self.error("Oldest frame")
979 return
976 return
980 try:
977 try:
981 count = int(arg or 1)
978 count = int(arg or 1)
982 except ValueError:
979 except ValueError:
983 self.error("Invalid frame count (%s)" % arg)
980 self.error("Invalid frame count (%s)" % arg)
984 return
981 return
985 skipped = 0
982 skipped = 0
986 if count < 0:
983 if count < 0:
987 _newframe = 0
984 _newframe = 0
988 else:
985 else:
989 counter = 0
986 counter = 0
990 hidden_frames = self.hidden_frames(self.stack)
987 hidden_frames = self.hidden_frames(self.stack)
991 for i in range(self.curindex - 1, -1, -1):
988 for i in range(self.curindex - 1, -1, -1):
992 if hidden_frames[i] and self.skip_hidden:
989 if hidden_frames[i] and self.skip_hidden:
993 skipped += 1
990 skipped += 1
994 continue
991 continue
995 counter += 1
992 counter += 1
996 if counter >= count:
993 if counter >= count:
997 break
994 break
998 else:
995 else:
999 # if no break occurred.
996 # if no break occurred.
1000 self.error(
997 self.error(
1001 "all frames above hidden, use `skip_hidden False` to get get into those."
998 "all frames above hidden, use `skip_hidden False` to get get into those."
1002 )
999 )
1003 return
1000 return
1004
1001
1005 Colors = self.color_scheme_table.active_colors
1002 Colors = self.color_scheme_table.active_colors
1006 ColorsNormal = Colors.Normal
1003 ColorsNormal = Colors.Normal
1007 _newframe = i
1004 _newframe = i
1008 self._select_frame(_newframe)
1005 self._select_frame(_newframe)
1009 if skipped:
1006 if skipped:
1010 print(
1007 print(
1011 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1008 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1012 )
1009 )
1013
1010
1014 def do_down(self, arg):
1011 def do_down(self, arg):
1015 """d(own) [count]
1012 """d(own) [count]
1016 Move the current frame count (default one) levels down in the
1013 Move the current frame count (default one) levels down in the
1017 stack trace (to a newer frame).
1014 stack trace (to a newer frame).
1018
1015
1019 Will skip hidden frames.
1016 Will skip hidden frames.
1020 """
1017 """
1021 if self.curindex + 1 == len(self.stack):
1018 if self.curindex + 1 == len(self.stack):
1022 self.error("Newest frame")
1019 self.error("Newest frame")
1023 return
1020 return
1024 try:
1021 try:
1025 count = int(arg or 1)
1022 count = int(arg or 1)
1026 except ValueError:
1023 except ValueError:
1027 self.error("Invalid frame count (%s)" % arg)
1024 self.error("Invalid frame count (%s)" % arg)
1028 return
1025 return
1029 if count < 0:
1026 if count < 0:
1030 _newframe = len(self.stack) - 1
1027 _newframe = len(self.stack) - 1
1031 else:
1028 else:
1032 counter = 0
1029 counter = 0
1033 skipped = 0
1030 skipped = 0
1034 hidden_frames = self.hidden_frames(self.stack)
1031 hidden_frames = self.hidden_frames(self.stack)
1035 for i in range(self.curindex + 1, len(self.stack)):
1032 for i in range(self.curindex + 1, len(self.stack)):
1036 if hidden_frames[i] and self.skip_hidden:
1033 if hidden_frames[i] and self.skip_hidden:
1037 skipped += 1
1034 skipped += 1
1038 continue
1035 continue
1039 counter += 1
1036 counter += 1
1040 if counter >= count:
1037 if counter >= count:
1041 break
1038 break
1042 else:
1039 else:
1043 self.error(
1040 self.error(
1044 "all frames below hidden, use `skip_hidden False` to get get into those."
1041 "all frames below hidden, use `skip_hidden False` to get get into those."
1045 )
1042 )
1046 return
1043 return
1047
1044
1048 Colors = self.color_scheme_table.active_colors
1045 Colors = self.color_scheme_table.active_colors
1049 ColorsNormal = Colors.Normal
1046 ColorsNormal = Colors.Normal
1050 if skipped:
1047 if skipped:
1051 print(
1048 print(
1052 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1049 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1053 )
1050 )
1054 _newframe = i
1051 _newframe = i
1055
1052
1056 self._select_frame(_newframe)
1053 self._select_frame(_newframe)
1057
1054
1058 do_d = do_down
1055 do_d = do_down
1059 do_u = do_up
1056 do_u = do_up
1060
1057
1061 def do_context(self, context):
1058 def do_context(self, context):
1062 """context number_of_lines
1059 """context number_of_lines
1063 Set the number of lines of source code to show when displaying
1060 Set the number of lines of source code to show when displaying
1064 stacktrace information.
1061 stacktrace information.
1065 """
1062 """
1066 try:
1063 try:
1067 new_context = int(context)
1064 new_context = int(context)
1068 if new_context <= 0:
1065 if new_context <= 0:
1069 raise ValueError()
1066 raise ValueError()
1070 self.context = new_context
1067 self.context = new_context
1071 except ValueError:
1068 except ValueError:
1072 self.error("The 'context' command requires a positive integer argument.")
1069 self.error("The 'context' command requires a positive integer argument.")
1073
1070
1074
1071
1075 class InterruptiblePdb(Pdb):
1072 class InterruptiblePdb(Pdb):
1076 """Version of debugger where KeyboardInterrupt exits the debugger altogether."""
1073 """Version of debugger where KeyboardInterrupt exits the debugger altogether."""
1077
1074
1078 def cmdloop(self, intro=None):
1075 def cmdloop(self, intro=None):
1079 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
1076 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
1080 try:
1077 try:
1081 return OldPdb.cmdloop(self, intro=intro)
1078 return OldPdb.cmdloop(self, intro=intro)
1082 except KeyboardInterrupt:
1079 except KeyboardInterrupt:
1083 self.stop_here = lambda frame: False
1080 self.stop_here = lambda frame: False
1084 self.do_quit("")
1081 self.do_quit("")
1085 sys.settrace(None)
1082 sys.settrace(None)
1086 self.quitting = False
1083 self.quitting = False
1087 raise
1084 raise
1088
1085
1089 def _cmdloop(self):
1086 def _cmdloop(self):
1090 while True:
1087 while True:
1091 try:
1088 try:
1092 # keyboard interrupts allow for an easy way to cancel
1089 # keyboard interrupts allow for an easy way to cancel
1093 # the current command, so allow them during interactive input
1090 # the current command, so allow them during interactive input
1094 self.allow_kbdint = True
1091 self.allow_kbdint = True
1095 self.cmdloop()
1092 self.cmdloop()
1096 self.allow_kbdint = False
1093 self.allow_kbdint = False
1097 break
1094 break
1098 except KeyboardInterrupt:
1095 except KeyboardInterrupt:
1099 self.message('--KeyboardInterrupt--')
1096 self.message('--KeyboardInterrupt--')
1100 raise
1097 raise
1101
1098
1102
1099
1103 def set_trace(frame=None):
1100 def set_trace(frame=None):
1104 """
1101 """
1105 Start debugging from `frame`.
1102 Start debugging from `frame`.
1106
1103
1107 If frame is not specified, debugging starts from caller's frame.
1104 If frame is not specified, debugging starts from caller's frame.
1108 """
1105 """
1109 Pdb().set_trace(frame or sys._getframe().f_back)
1106 Pdb().set_trace(frame or sys._getframe().f_back)
@@ -1,1517 +1,1516 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
417 @magic_arguments.magic_arguments()
416 @magic_arguments.magic_arguments()
418 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
417 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
419 help="""
418 help="""
420 Set break point at LINE in FILE.
419 Set break point at LINE in FILE.
421 """
420 """
422 )
421 )
423 @magic_arguments.argument('statement', nargs='*',
422 @magic_arguments.argument('statement', nargs='*',
424 help="""
423 help="""
425 Code to run in debugger.
424 Code to run in debugger.
426 You can omit this in cell magic mode.
425 You can omit this in cell magic mode.
427 """
426 """
428 )
427 )
429 @no_var_expand
428 @no_var_expand
430 @line_cell_magic
429 @line_cell_magic
431 def debug(self, line='', cell=None):
430 def debug(self, line='', cell=None):
432 """Activate the interactive debugger.
431 """Activate the interactive debugger.
433
432
434 This magic command support two ways of activating debugger.
433 This magic command support two ways of activating debugger.
435 One is to activate debugger before executing code. This way, you
434 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.
435 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
436 You can use this mode by giving statements to execute and optionally
438 a breakpoint.
437 a breakpoint.
439
438
440 The other one is to activate debugger in post-mortem mode. You can
439 The other one is to activate debugger in post-mortem mode. You can
441 activate this mode simply running %debug without any argument.
440 activate this mode simply running %debug without any argument.
442 If an exception has just occurred, this lets you inspect its stack
441 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
442 frames interactively. Note that this will always work only on the last
444 traceback that occurred, so you must call this quickly after an
443 traceback that occurred, so you must call this quickly after an
445 exception that you wish to inspect has fired, because if another one
444 exception that you wish to inspect has fired, because if another one
446 occurs, it clobbers the previous one.
445 occurs, it clobbers the previous one.
447
446
448 If you want IPython to automatically do this on every exception, see
447 If you want IPython to automatically do this on every exception, see
449 the %pdb magic for more details.
448 the %pdb magic for more details.
450
449
451 .. versionchanged:: 7.3
450 .. versionchanged:: 7.3
452 When running code, user variables are no longer expanded,
451 When running code, user variables are no longer expanded,
453 the magic line is always left unmodified.
452 the magic line is always left unmodified.
454
453
455 """
454 """
456 args = magic_arguments.parse_argstring(self.debug, line)
455 args = magic_arguments.parse_argstring(self.debug, line)
457
456
458 if not (args.breakpoint or args.statement or cell):
457 if not (args.breakpoint or args.statement or cell):
459 self._debug_post_mortem()
458 self._debug_post_mortem()
460 elif not (args.breakpoint or cell):
459 elif not (args.breakpoint or cell):
461 # If there is no breakpoints, the line is just code to execute
460 # If there is no breakpoints, the line is just code to execute
462 self._debug_exec(line, None)
461 self._debug_exec(line, None)
463 else:
462 else:
464 # Here we try to reconstruct the code from the output of
463 # Here we try to reconstruct the code from the output of
465 # parse_argstring. This might not work if the code has spaces
464 # parse_argstring. This might not work if the code has spaces
466 # For example this fails for `print("a b")`
465 # For example this fails for `print("a b")`
467 code = "\n".join(args.statement)
466 code = "\n".join(args.statement)
468 if cell:
467 if cell:
469 code += "\n" + cell
468 code += "\n" + cell
470 self._debug_exec(code, args.breakpoint)
469 self._debug_exec(code, args.breakpoint)
471
470
472 def _debug_post_mortem(self):
471 def _debug_post_mortem(self):
473 self.shell.debugger(force=True)
472 self.shell.debugger(force=True)
474
473
475 def _debug_exec(self, code, breakpoint):
474 def _debug_exec(self, code, breakpoint):
476 if breakpoint:
475 if breakpoint:
477 (filename, bp_line) = breakpoint.rsplit(':', 1)
476 (filename, bp_line) = breakpoint.rsplit(':', 1)
478 bp_line = int(bp_line)
477 bp_line = int(bp_line)
479 else:
478 else:
480 (filename, bp_line) = (None, None)
479 (filename, bp_line) = (None, None)
481 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
480 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
482
481
483 @line_magic
482 @line_magic
484 def tb(self, s):
483 def tb(self, s):
485 """Print the last traceback.
484 """Print the last traceback.
486
485
487 Optionally, specify an exception reporting mode, tuning the
486 Optionally, specify an exception reporting mode, tuning the
488 verbosity of the traceback. By default the currently-active exception
487 verbosity of the traceback. By default the currently-active exception
489 mode is used. See %xmode for changing exception reporting modes.
488 mode is used. See %xmode for changing exception reporting modes.
490
489
491 Valid modes: Plain, Context, Verbose, and Minimal.
490 Valid modes: Plain, Context, Verbose, and Minimal.
492 """
491 """
493 interactive_tb = self.shell.InteractiveTB
492 interactive_tb = self.shell.InteractiveTB
494 if s:
493 if s:
495 # Switch exception reporting mode for this one call.
494 # Switch exception reporting mode for this one call.
496 # Ensure it is switched back.
495 # Ensure it is switched back.
497 def xmode_switch_err(name):
496 def xmode_switch_err(name):
498 warn('Error changing %s exception modes.\n%s' %
497 warn('Error changing %s exception modes.\n%s' %
499 (name,sys.exc_info()[1]))
498 (name,sys.exc_info()[1]))
500
499
501 new_mode = s.strip().capitalize()
500 new_mode = s.strip().capitalize()
502 original_mode = interactive_tb.mode
501 original_mode = interactive_tb.mode
503 try:
502 try:
504 try:
503 try:
505 interactive_tb.set_mode(mode=new_mode)
504 interactive_tb.set_mode(mode=new_mode)
506 except Exception:
505 except Exception:
507 xmode_switch_err('user')
506 xmode_switch_err('user')
508 else:
507 else:
509 self.shell.showtraceback()
508 self.shell.showtraceback()
510 finally:
509 finally:
511 interactive_tb.set_mode(mode=original_mode)
510 interactive_tb.set_mode(mode=original_mode)
512 else:
511 else:
513 self.shell.showtraceback()
512 self.shell.showtraceback()
514
513
515 @skip_doctest
514 @skip_doctest
516 @line_magic
515 @line_magic
517 def run(self, parameter_s='', runner=None,
516 def run(self, parameter_s='', runner=None,
518 file_finder=get_py_filename):
517 file_finder=get_py_filename):
519 """Run the named file inside IPython as a program.
518 """Run the named file inside IPython as a program.
520
519
521 Usage::
520 Usage::
522
521
523 %run [-n -i -e -G]
522 %run [-n -i -e -G]
524 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
523 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
525 ( -m mod | filename ) [args]
524 ( -m mod | filename ) [args]
526
525
527 The filename argument should be either a pure Python script (with
526 The filename argument should be either a pure Python script (with
528 extension ``.py``), or a file with custom IPython syntax (such as
527 extension ``.py``), or a file with custom IPython syntax (such as
529 magics). If the latter, the file can be either a script with ``.ipy``
528 magics). If the latter, the file can be either a script with ``.ipy``
530 extension, or a Jupyter notebook with ``.ipynb`` extension. When running
529 extension, or a Jupyter notebook with ``.ipynb`` extension. When running
531 a Jupyter notebook, the output from print statements and other
530 a Jupyter notebook, the output from print statements and other
532 displayed objects will appear in the terminal (even matplotlib figures
531 displayed objects will appear in the terminal (even matplotlib figures
533 will open, if a terminal-compliant backend is being used). Note that,
532 will open, if a terminal-compliant backend is being used). Note that,
534 at the system command line, the ``jupyter run`` command offers similar
533 at the system command line, the ``jupyter run`` command offers similar
535 functionality for executing notebooks (albeit currently with some
534 functionality for executing notebooks (albeit currently with some
536 differences in supported options).
535 differences in supported options).
537
536
538 Parameters after the filename are passed as command-line arguments to
537 Parameters after the filename are passed as command-line arguments to
539 the program (put in sys.argv). Then, control returns to IPython's
538 the program (put in sys.argv). Then, control returns to IPython's
540 prompt.
539 prompt.
541
540
542 This is similar to running at a system prompt ``python file args``,
541 This is similar to running at a system prompt ``python file args``,
543 but with the advantage of giving you IPython's tracebacks, and of
542 but with the advantage of giving you IPython's tracebacks, and of
544 loading all variables into your interactive namespace for further use
543 loading all variables into your interactive namespace for further use
545 (unless -p is used, see below).
544 (unless -p is used, see below).
546
545
547 The file is executed in a namespace initially consisting only of
546 The file is executed in a namespace initially consisting only of
548 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
547 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
549 sees its environment as if it were being run as a stand-alone program
548 sees its environment as if it were being run as a stand-alone program
550 (except for sharing global objects such as previously imported
549 (except for sharing global objects such as previously imported
551 modules). But after execution, the IPython interactive namespace gets
550 modules). But after execution, the IPython interactive namespace gets
552 updated with all variables defined in the program (except for __name__
551 updated with all variables defined in the program (except for __name__
553 and sys.argv). This allows for very convenient loading of code for
552 and sys.argv). This allows for very convenient loading of code for
554 interactive work, while giving each program a 'clean sheet' to run in.
553 interactive work, while giving each program a 'clean sheet' to run in.
555
554
556 Arguments are expanded using shell-like glob match. Patterns
555 Arguments are expanded using shell-like glob match. Patterns
557 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
556 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
558 tilde '~' will be expanded into user's home directory. Unlike
557 tilde '~' will be expanded into user's home directory. Unlike
559 real shells, quotation does not suppress expansions. Use
558 real shells, quotation does not suppress expansions. Use
560 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
559 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
561 To completely disable these expansions, you can use -G flag.
560 To completely disable these expansions, you can use -G flag.
562
561
563 On Windows systems, the use of single quotes `'` when specifying
562 On Windows systems, the use of single quotes `'` when specifying
564 a file is not supported. Use double quotes `"`.
563 a file is not supported. Use double quotes `"`.
565
564
566 Options:
565 Options:
567
566
568 -n
567 -n
569 __name__ is NOT set to '__main__', but to the running file's name
568 __name__ is NOT set to '__main__', but to the running file's name
570 without extension (as python does under import). This allows running
569 without extension (as python does under import). This allows running
571 scripts and reloading the definitions in them without calling code
570 scripts and reloading the definitions in them without calling code
572 protected by an ``if __name__ == "__main__"`` clause.
571 protected by an ``if __name__ == "__main__"`` clause.
573
572
574 -i
573 -i
575 run the file in IPython's namespace instead of an empty one. This
574 run the file in IPython's namespace instead of an empty one. This
576 is useful if you are experimenting with code written in a text editor
575 is useful if you are experimenting with code written in a text editor
577 which depends on variables defined interactively.
576 which depends on variables defined interactively.
578
577
579 -e
578 -e
580 ignore sys.exit() calls or SystemExit exceptions in the script
579 ignore sys.exit() calls or SystemExit exceptions in the script
581 being run. This is particularly useful if IPython is being used to
580 being run. This is particularly useful if IPython is being used to
582 run unittests, which always exit with a sys.exit() call. In such
581 run unittests, which always exit with a sys.exit() call. In such
583 cases you are interested in the output of the test results, not in
582 cases you are interested in the output of the test results, not in
584 seeing a traceback of the unittest module.
583 seeing a traceback of the unittest module.
585
584
586 -t
585 -t
587 print timing information at the end of the run. IPython will give
586 print timing information at the end of the run. IPython will give
588 you an estimated CPU time consumption for your script, which under
587 you an estimated CPU time consumption for your script, which under
589 Unix uses the resource module to avoid the wraparound problems of
588 Unix uses the resource module to avoid the wraparound problems of
590 time.clock(). Under Unix, an estimate of time spent on system tasks
589 time.clock(). Under Unix, an estimate of time spent on system tasks
591 is also given (for Windows platforms this is reported as 0.0).
590 is also given (for Windows platforms this is reported as 0.0).
592
591
593 If -t is given, an additional ``-N<N>`` option can be given, where <N>
592 If -t is given, an additional ``-N<N>`` option can be given, where <N>
594 must be an integer indicating how many times you want the script to
593 must be an integer indicating how many times you want the script to
595 run. The final timing report will include total and per run results.
594 run. The final timing report will include total and per run results.
596
595
597 For example (testing the script uniq_stable.py)::
596 For example (testing the script uniq_stable.py)::
598
597
599 In [1]: run -t uniq_stable
598 In [1]: run -t uniq_stable
600
599
601 IPython CPU timings (estimated):
600 IPython CPU timings (estimated):
602 User : 0.19597 s.
601 User : 0.19597 s.
603 System: 0.0 s.
602 System: 0.0 s.
604
603
605 In [2]: run -t -N5 uniq_stable
604 In [2]: run -t -N5 uniq_stable
606
605
607 IPython CPU timings (estimated):
606 IPython CPU timings (estimated):
608 Total runs performed: 5
607 Total runs performed: 5
609 Times : Total Per run
608 Times : Total Per run
610 User : 0.910862 s, 0.1821724 s.
609 User : 0.910862 s, 0.1821724 s.
611 System: 0.0 s, 0.0 s.
610 System: 0.0 s, 0.0 s.
612
611
613 -d
612 -d
614 run your program under the control of pdb, the Python debugger.
613 run your program under the control of pdb, the Python debugger.
615 This allows you to execute your program step by step, watch variables,
614 This allows you to execute your program step by step, watch variables,
616 etc. Internally, what IPython does is similar to calling::
615 etc. Internally, what IPython does is similar to calling::
617
616
618 pdb.run('execfile("YOURFILENAME")')
617 pdb.run('execfile("YOURFILENAME")')
619
618
620 with a breakpoint set on line 1 of your file. You can change the line
619 with a breakpoint set on line 1 of your file. You can change the line
621 number for this automatic breakpoint to be <N> by using the -bN option
620 number for this automatic breakpoint to be <N> by using the -bN option
622 (where N must be an integer). For example::
621 (where N must be an integer). For example::
623
622
624 %run -d -b40 myscript
623 %run -d -b40 myscript
625
624
626 will set the first breakpoint at line 40 in myscript.py. Note that
625 will set the first breakpoint at line 40 in myscript.py. Note that
627 the first breakpoint must be set on a line which actually does
626 the first breakpoint must be set on a line which actually does
628 something (not a comment or docstring) for it to stop execution.
627 something (not a comment or docstring) for it to stop execution.
629
628
630 Or you can specify a breakpoint in a different file::
629 Or you can specify a breakpoint in a different file::
631
630
632 %run -d -b myotherfile.py:20 myscript
631 %run -d -b myotherfile.py:20 myscript
633
632
634 When the pdb debugger starts, you will see a (Pdb) prompt. You must
633 When the pdb debugger starts, you will see a (Pdb) prompt. You must
635 first enter 'c' (without quotes) to start execution up to the first
634 first enter 'c' (without quotes) to start execution up to the first
636 breakpoint.
635 breakpoint.
637
636
638 Entering 'help' gives information about the use of the debugger. You
637 Entering 'help' gives information about the use of the debugger. You
639 can easily see pdb's full documentation with "import pdb;pdb.help()"
638 can easily see pdb's full documentation with "import pdb;pdb.help()"
640 at a prompt.
639 at a prompt.
641
640
642 -p
641 -p
643 run program under the control of the Python profiler module (which
642 run program under the control of the Python profiler module (which
644 prints a detailed report of execution times, function calls, etc).
643 prints a detailed report of execution times, function calls, etc).
645
644
646 You can pass other options after -p which affect the behavior of the
645 You can pass other options after -p which affect the behavior of the
647 profiler itself. See the docs for %prun for details.
646 profiler itself. See the docs for %prun for details.
648
647
649 In this mode, the program's variables do NOT propagate back to the
648 In this mode, the program's variables do NOT propagate back to the
650 IPython interactive namespace (because they remain in the namespace
649 IPython interactive namespace (because they remain in the namespace
651 where the profiler executes them).
650 where the profiler executes them).
652
651
653 Internally this triggers a call to %prun, see its documentation for
652 Internally this triggers a call to %prun, see its documentation for
654 details on the options available specifically for profiling.
653 details on the options available specifically for profiling.
655
654
656 There is one special usage for which the text above doesn't apply:
655 There is one special usage for which the text above doesn't apply:
657 if the filename ends with .ipy[nb], the file is run as ipython script,
656 if the filename ends with .ipy[nb], the file is run as ipython script,
658 just as if the commands were written on IPython prompt.
657 just as if the commands were written on IPython prompt.
659
658
660 -m
659 -m
661 specify module name to load instead of script path. Similar to
660 specify module name to load instead of script path. Similar to
662 the -m option for the python interpreter. Use this option last if you
661 the -m option for the python interpreter. Use this option last if you
663 want to combine with other %run options. Unlike the python interpreter
662 want to combine with other %run options. Unlike the python interpreter
664 only source modules are allowed no .pyc or .pyo files.
663 only source modules are allowed no .pyc or .pyo files.
665 For example::
664 For example::
666
665
667 %run -m example
666 %run -m example
668
667
669 will run the example module.
668 will run the example module.
670
669
671 -G
670 -G
672 disable shell-like glob expansion of arguments.
671 disable shell-like glob expansion of arguments.
673
672
674 """
673 """
675
674
676 # Logic to handle issue #3664
675 # Logic to handle issue #3664
677 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
676 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
678 if '-m' in parameter_s and '--' not in parameter_s:
677 if '-m' in parameter_s and '--' not in parameter_s:
679 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
678 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
680 for idx, arg in enumerate(argv):
679 for idx, arg in enumerate(argv):
681 if arg and arg.startswith('-') and arg != '-':
680 if arg and arg.startswith('-') and arg != '-':
682 if arg == '-m':
681 if arg == '-m':
683 argv.insert(idx + 2, '--')
682 argv.insert(idx + 2, '--')
684 break
683 break
685 else:
684 else:
686 # Positional arg, break
685 # Positional arg, break
687 break
686 break
688 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
687 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
689
688
690 # get arguments and set sys.argv for program to be run.
689 # get arguments and set sys.argv for program to be run.
691 opts, arg_lst = self.parse_options(parameter_s,
690 opts, arg_lst = self.parse_options(parameter_s,
692 'nidtN:b:pD:l:rs:T:em:G',
691 'nidtN:b:pD:l:rs:T:em:G',
693 mode='list', list_all=1)
692 mode='list', list_all=1)
694 if "m" in opts:
693 if "m" in opts:
695 modulename = opts["m"][0]
694 modulename = opts["m"][0]
696 modpath = find_mod(modulename)
695 modpath = find_mod(modulename)
697 if modpath is None:
696 if modpath is None:
698 msg = '%r is not a valid modulename on sys.path'%modulename
697 msg = '%r is not a valid modulename on sys.path'%modulename
699 raise Exception(msg)
698 raise Exception(msg)
700 arg_lst = [modpath] + arg_lst
699 arg_lst = [modpath] + arg_lst
701 try:
700 try:
702 fpath = None # initialize to make sure fpath is in scope later
701 fpath = None # initialize to make sure fpath is in scope later
703 fpath = arg_lst[0]
702 fpath = arg_lst[0]
704 filename = file_finder(fpath)
703 filename = file_finder(fpath)
705 except IndexError as e:
704 except IndexError as e:
706 msg = 'you must provide at least a filename.'
705 msg = 'you must provide at least a filename.'
707 raise Exception(msg) from e
706 raise Exception(msg) from e
708 except IOError as e:
707 except IOError as e:
709 try:
708 try:
710 msg = str(e)
709 msg = str(e)
711 except UnicodeError:
710 except UnicodeError:
712 msg = e.message
711 msg = e.message
713 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
712 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
714 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
713 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
715 raise Exception(msg) from e
714 raise Exception(msg) from e
716 except TypeError:
715 except TypeError:
717 if fpath in sys.meta_path:
716 if fpath in sys.meta_path:
718 filename = ""
717 filename = ""
719 else:
718 else:
720 raise
719 raise
721
720
722 if filename.lower().endswith(('.ipy', '.ipynb')):
721 if filename.lower().endswith(('.ipy', '.ipynb')):
723 with preserve_keys(self.shell.user_ns, '__file__'):
722 with preserve_keys(self.shell.user_ns, '__file__'):
724 self.shell.user_ns['__file__'] = filename
723 self.shell.user_ns['__file__'] = filename
725 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
724 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
726 return
725 return
727
726
728 # Control the response to exit() calls made by the script being run
727 # Control the response to exit() calls made by the script being run
729 exit_ignore = 'e' in opts
728 exit_ignore = 'e' in opts
730
729
731 # Make sure that the running script gets a proper sys.argv as if it
730 # Make sure that the running script gets a proper sys.argv as if it
732 # were run from a system shell.
731 # were run from a system shell.
733 save_argv = sys.argv # save it for later restoring
732 save_argv = sys.argv # save it for later restoring
734
733
735 if 'G' in opts:
734 if 'G' in opts:
736 args = arg_lst[1:]
735 args = arg_lst[1:]
737 else:
736 else:
738 # tilde and glob expansion
737 # tilde and glob expansion
739 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
738 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
740
739
741 sys.argv = [filename] + args # put in the proper filename
740 sys.argv = [filename] + args # put in the proper filename
742
741
743 if 'n' in opts:
742 if 'n' in opts:
744 name = Path(filename).stem
743 name = Path(filename).stem
745 else:
744 else:
746 name = '__main__'
745 name = '__main__'
747
746
748 if 'i' in opts:
747 if 'i' in opts:
749 # Run in user's interactive namespace
748 # Run in user's interactive namespace
750 prog_ns = self.shell.user_ns
749 prog_ns = self.shell.user_ns
751 __name__save = self.shell.user_ns['__name__']
750 __name__save = self.shell.user_ns['__name__']
752 prog_ns['__name__'] = name
751 prog_ns['__name__'] = name
753 main_mod = self.shell.user_module
752 main_mod = self.shell.user_module
754
753
755 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
754 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
756 # set the __file__ global in the script's namespace
755 # set the __file__ global in the script's namespace
757 # TK: Is this necessary in interactive mode?
756 # TK: Is this necessary in interactive mode?
758 prog_ns['__file__'] = filename
757 prog_ns['__file__'] = filename
759 else:
758 else:
760 # Run in a fresh, empty namespace
759 # Run in a fresh, empty namespace
761
760
762 # The shell MUST hold a reference to prog_ns so after %run
761 # The shell MUST hold a reference to prog_ns so after %run
763 # exits, the python deletion mechanism doesn't zero it out
762 # exits, the python deletion mechanism doesn't zero it out
764 # (leaving dangling references). See interactiveshell for details
763 # (leaving dangling references). See interactiveshell for details
765 main_mod = self.shell.new_main_mod(filename, name)
764 main_mod = self.shell.new_main_mod(filename, name)
766 prog_ns = main_mod.__dict__
765 prog_ns = main_mod.__dict__
767
766
768 # pickle fix. See interactiveshell for an explanation. But we need to
767 # pickle fix. See interactiveshell for an explanation. But we need to
769 # make sure that, if we overwrite __main__, we replace it at the end
768 # make sure that, if we overwrite __main__, we replace it at the end
770 main_mod_name = prog_ns['__name__']
769 main_mod_name = prog_ns['__name__']
771
770
772 if main_mod_name == '__main__':
771 if main_mod_name == '__main__':
773 restore_main = sys.modules['__main__']
772 restore_main = sys.modules['__main__']
774 else:
773 else:
775 restore_main = False
774 restore_main = False
776
775
777 # This needs to be undone at the end to prevent holding references to
776 # This needs to be undone at the end to prevent holding references to
778 # every single object ever created.
777 # every single object ever created.
779 sys.modules[main_mod_name] = main_mod
778 sys.modules[main_mod_name] = main_mod
780
779
781 if 'p' in opts or 'd' in opts:
780 if 'p' in opts or 'd' in opts:
782 if 'm' in opts:
781 if 'm' in opts:
783 code = 'run_module(modulename, prog_ns)'
782 code = 'run_module(modulename, prog_ns)'
784 code_ns = {
783 code_ns = {
785 'run_module': self.shell.safe_run_module,
784 'run_module': self.shell.safe_run_module,
786 'prog_ns': prog_ns,
785 'prog_ns': prog_ns,
787 'modulename': modulename,
786 'modulename': modulename,
788 }
787 }
789 else:
788 else:
790 if 'd' in opts:
789 if 'd' in opts:
791 # allow exceptions to raise in debug mode
790 # allow exceptions to raise in debug mode
792 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
791 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
793 else:
792 else:
794 code = 'execfile(filename, prog_ns)'
793 code = 'execfile(filename, prog_ns)'
795 code_ns = {
794 code_ns = {
796 'execfile': self.shell.safe_execfile,
795 'execfile': self.shell.safe_execfile,
797 'prog_ns': prog_ns,
796 'prog_ns': prog_ns,
798 'filename': get_py_filename(filename),
797 'filename': get_py_filename(filename),
799 }
798 }
800
799
801 try:
800 try:
802 stats = None
801 stats = None
803 if 'p' in opts:
802 if 'p' in opts:
804 stats = self._run_with_profiler(code, opts, code_ns)
803 stats = self._run_with_profiler(code, opts, code_ns)
805 else:
804 else:
806 if 'd' in opts:
805 if 'd' in opts:
807 bp_file, bp_line = parse_breakpoint(
806 bp_file, bp_line = parse_breakpoint(
808 opts.get('b', ['1'])[0], filename)
807 opts.get('b', ['1'])[0], filename)
809 self._run_with_debugger(
808 self._run_with_debugger(
810 code, code_ns, filename, bp_line, bp_file)
809 code, code_ns, filename, bp_line, bp_file)
811 else:
810 else:
812 if 'm' in opts:
811 if 'm' in opts:
813 def run():
812 def run():
814 self.shell.safe_run_module(modulename, prog_ns)
813 self.shell.safe_run_module(modulename, prog_ns)
815 else:
814 else:
816 if runner is None:
815 if runner is None:
817 runner = self.default_runner
816 runner = self.default_runner
818 if runner is None:
817 if runner is None:
819 runner = self.shell.safe_execfile
818 runner = self.shell.safe_execfile
820
819
821 def run():
820 def run():
822 runner(filename, prog_ns, prog_ns,
821 runner(filename, prog_ns, prog_ns,
823 exit_ignore=exit_ignore)
822 exit_ignore=exit_ignore)
824
823
825 if 't' in opts:
824 if 't' in opts:
826 # timed execution
825 # timed execution
827 try:
826 try:
828 nruns = int(opts['N'][0])
827 nruns = int(opts['N'][0])
829 if nruns < 1:
828 if nruns < 1:
830 error('Number of runs must be >=1')
829 error('Number of runs must be >=1')
831 return
830 return
832 except (KeyError):
831 except (KeyError):
833 nruns = 1
832 nruns = 1
834 self._run_with_timing(run, nruns)
833 self._run_with_timing(run, nruns)
835 else:
834 else:
836 # regular execution
835 # regular execution
837 run()
836 run()
838
837
839 if 'i' in opts:
838 if 'i' in opts:
840 self.shell.user_ns['__name__'] = __name__save
839 self.shell.user_ns['__name__'] = __name__save
841 else:
840 else:
842 # update IPython interactive namespace
841 # update IPython interactive namespace
843
842
844 # Some forms of read errors on the file may mean the
843 # Some forms of read errors on the file may mean the
845 # __name__ key was never set; using pop we don't have to
844 # __name__ key was never set; using pop we don't have to
846 # worry about a possible KeyError.
845 # worry about a possible KeyError.
847 prog_ns.pop('__name__', None)
846 prog_ns.pop('__name__', None)
848
847
849 with preserve_keys(self.shell.user_ns, '__file__'):
848 with preserve_keys(self.shell.user_ns, '__file__'):
850 self.shell.user_ns.update(prog_ns)
849 self.shell.user_ns.update(prog_ns)
851 finally:
850 finally:
852 # It's a bit of a mystery why, but __builtins__ can change from
851 # It's a bit of a mystery why, but __builtins__ can change from
853 # being a module to becoming a dict missing some key data after
852 # being a module to becoming a dict missing some key data after
854 # %run. As best I can see, this is NOT something IPython is doing
853 # %run. As best I can see, this is NOT something IPython is doing
855 # at all, and similar problems have been reported before:
854 # at all, and similar problems have been reported before:
856 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
855 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
857 # Since this seems to be done by the interpreter itself, the best
856 # Since this seems to be done by the interpreter itself, the best
858 # we can do is to at least restore __builtins__ for the user on
857 # we can do is to at least restore __builtins__ for the user on
859 # exit.
858 # exit.
860 self.shell.user_ns['__builtins__'] = builtin_mod
859 self.shell.user_ns['__builtins__'] = builtin_mod
861
860
862 # Ensure key global structures are restored
861 # Ensure key global structures are restored
863 sys.argv = save_argv
862 sys.argv = save_argv
864 if restore_main:
863 if restore_main:
865 sys.modules['__main__'] = restore_main
864 sys.modules['__main__'] = restore_main
866 if '__mp_main__' in sys.modules:
865 if '__mp_main__' in sys.modules:
867 sys.modules['__mp_main__'] = restore_main
866 sys.modules['__mp_main__'] = restore_main
868 else:
867 else:
869 # Remove from sys.modules the reference to main_mod we'd
868 # Remove from sys.modules the reference to main_mod we'd
870 # added. Otherwise it will trap references to objects
869 # added. Otherwise it will trap references to objects
871 # contained therein.
870 # contained therein.
872 del sys.modules[main_mod_name]
871 del sys.modules[main_mod_name]
873
872
874 return stats
873 return stats
875
874
876 def _run_with_debugger(self, code, code_ns, filename=None,
875 def _run_with_debugger(self, code, code_ns, filename=None,
877 bp_line=None, bp_file=None):
876 bp_line=None, bp_file=None):
878 """
877 """
879 Run `code` in debugger with a break point.
878 Run `code` in debugger with a break point.
880
879
881 Parameters
880 Parameters
882 ----------
881 ----------
883 code : str
882 code : str
884 Code to execute.
883 Code to execute.
885 code_ns : dict
884 code_ns : dict
886 A namespace in which `code` is executed.
885 A namespace in which `code` is executed.
887 filename : str
886 filename : str
888 `code` is ran as if it is in `filename`.
887 `code` is ran as if it is in `filename`.
889 bp_line : int, optional
888 bp_line : int, optional
890 Line number of the break point.
889 Line number of the break point.
891 bp_file : str, optional
890 bp_file : str, optional
892 Path to the file in which break point is specified.
891 Path to the file in which break point is specified.
893 `filename` is used if not given.
892 `filename` is used if not given.
894
893
895 Raises
894 Raises
896 ------
895 ------
897 UsageError
896 UsageError
898 If the break point given by `bp_line` is not valid.
897 If the break point given by `bp_line` is not valid.
899
898
900 """
899 """
901 deb = self.shell.InteractiveTB.pdb
900 deb = self.shell.InteractiveTB.pdb
902 if not deb:
901 if not deb:
903 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
902 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
904 deb = self.shell.InteractiveTB.pdb
903 deb = self.shell.InteractiveTB.pdb
905
904
906 # deb.checkline() fails if deb.curframe exists but is None; it can
905 # deb.checkline() fails if deb.curframe exists but is None; it can
907 # handle it not existing. https://github.com/ipython/ipython/issues/10028
906 # handle it not existing. https://github.com/ipython/ipython/issues/10028
908 if hasattr(deb, 'curframe'):
907 if hasattr(deb, 'curframe'):
909 del deb.curframe
908 del deb.curframe
910
909
911 # reset Breakpoint state, which is moronically kept
910 # reset Breakpoint state, which is moronically kept
912 # in a class
911 # in a class
913 bdb.Breakpoint.next = 1
912 bdb.Breakpoint.next = 1
914 bdb.Breakpoint.bplist = {}
913 bdb.Breakpoint.bplist = {}
915 bdb.Breakpoint.bpbynumber = [None]
914 bdb.Breakpoint.bpbynumber = [None]
916 deb.clear_all_breaks()
915 deb.clear_all_breaks()
917 if bp_line is not None:
916 if bp_line is not None:
918 # Set an initial breakpoint to stop execution
917 # Set an initial breakpoint to stop execution
919 maxtries = 10
918 maxtries = 10
920 bp_file = bp_file or filename
919 bp_file = bp_file or filename
921 checkline = deb.checkline(bp_file, bp_line)
920 checkline = deb.checkline(bp_file, bp_line)
922 if not checkline:
921 if not checkline:
923 for bp in range(bp_line + 1, bp_line + maxtries + 1):
922 for bp in range(bp_line + 1, bp_line + maxtries + 1):
924 if deb.checkline(bp_file, bp):
923 if deb.checkline(bp_file, bp):
925 break
924 break
926 else:
925 else:
927 msg = ("\nI failed to find a valid line to set "
926 msg = ("\nI failed to find a valid line to set "
928 "a breakpoint\n"
927 "a breakpoint\n"
929 "after trying up to line: %s.\n"
928 "after trying up to line: %s.\n"
930 "Please set a valid breakpoint manually "
929 "Please set a valid breakpoint manually "
931 "with the -b option." % bp)
930 "with the -b option." % bp)
932 raise UsageError(msg)
931 raise UsageError(msg)
933 # if we find a good linenumber, set the breakpoint
932 # if we find a good linenumber, set the breakpoint
934 deb.do_break('%s:%s' % (bp_file, bp_line))
933 deb.do_break('%s:%s' % (bp_file, bp_line))
935
934
936 if filename:
935 if filename:
937 # Mimic Pdb._runscript(...)
936 # Mimic Pdb._runscript(...)
938 deb._wait_for_mainpyfile = True
937 deb._wait_for_mainpyfile = True
939 deb.mainpyfile = deb.canonic(filename)
938 deb.mainpyfile = deb.canonic(filename)
940
939
941 # Start file run
940 # Start file run
942 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
941 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
943 try:
942 try:
944 if filename:
943 if filename:
945 # save filename so it can be used by methods on the deb object
944 # save filename so it can be used by methods on the deb object
946 deb._exec_filename = filename
945 deb._exec_filename = filename
947 while True:
946 while True:
948 try:
947 try:
949 trace = sys.gettrace()
948 trace = sys.gettrace()
950 deb.run(code, code_ns)
949 deb.run(code, code_ns)
951 except Restart:
950 except Restart:
952 print("Restarting")
951 print("Restarting")
953 if filename:
952 if filename:
954 deb._wait_for_mainpyfile = True
953 deb._wait_for_mainpyfile = True
955 deb.mainpyfile = deb.canonic(filename)
954 deb.mainpyfile = deb.canonic(filename)
956 continue
955 continue
957 else:
956 else:
958 break
957 break
959 finally:
958 finally:
960 sys.settrace(trace)
959 sys.settrace(trace)
961
960
962
961
963 except:
962 except:
964 etype, value, tb = sys.exc_info()
963 etype, value, tb = sys.exc_info()
965 # Skip three frames in the traceback: the %run one,
964 # Skip three frames in the traceback: the %run one,
966 # one inside bdb.py, and the command-line typed by the
965 # one inside bdb.py, and the command-line typed by the
967 # user (run by exec in pdb itself).
966 # user (run by exec in pdb itself).
968 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
967 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
969
968
970 @staticmethod
969 @staticmethod
971 def _run_with_timing(run, nruns):
970 def _run_with_timing(run, nruns):
972 """
971 """
973 Run function `run` and print timing information.
972 Run function `run` and print timing information.
974
973
975 Parameters
974 Parameters
976 ----------
975 ----------
977 run : callable
976 run : callable
978 Any callable object which takes no argument.
977 Any callable object which takes no argument.
979 nruns : int
978 nruns : int
980 Number of times to execute `run`.
979 Number of times to execute `run`.
981
980
982 """
981 """
983 twall0 = time.perf_counter()
982 twall0 = time.perf_counter()
984 if nruns == 1:
983 if nruns == 1:
985 t0 = clock2()
984 t0 = clock2()
986 run()
985 run()
987 t1 = clock2()
986 t1 = clock2()
988 t_usr = t1[0] - t0[0]
987 t_usr = t1[0] - t0[0]
989 t_sys = t1[1] - t0[1]
988 t_sys = t1[1] - t0[1]
990 print("\nIPython CPU timings (estimated):")
989 print("\nIPython CPU timings (estimated):")
991 print(" User : %10.2f s." % t_usr)
990 print(" User : %10.2f s." % t_usr)
992 print(" System : %10.2f s." % t_sys)
991 print(" System : %10.2f s." % t_sys)
993 else:
992 else:
994 runs = range(nruns)
993 runs = range(nruns)
995 t0 = clock2()
994 t0 = clock2()
996 for nr in runs:
995 for nr in runs:
997 run()
996 run()
998 t1 = clock2()
997 t1 = clock2()
999 t_usr = t1[0] - t0[0]
998 t_usr = t1[0] - t0[0]
1000 t_sys = t1[1] - t0[1]
999 t_sys = t1[1] - t0[1]
1001 print("\nIPython CPU timings (estimated):")
1000 print("\nIPython CPU timings (estimated):")
1002 print("Total runs performed:", nruns)
1001 print("Total runs performed:", nruns)
1003 print(" Times : %10s %10s" % ('Total', 'Per run'))
1002 print(" Times : %10s %10s" % ('Total', 'Per run'))
1004 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
1003 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
1005 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
1004 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
1006 twall1 = time.perf_counter()
1005 twall1 = time.perf_counter()
1007 print("Wall time: %10.2f s." % (twall1 - twall0))
1006 print("Wall time: %10.2f s." % (twall1 - twall0))
1008
1007
1009 @skip_doctest
1008 @skip_doctest
1010 @no_var_expand
1009 @no_var_expand
1011 @line_cell_magic
1010 @line_cell_magic
1012 @needs_local_scope
1011 @needs_local_scope
1013 def timeit(self, line='', cell=None, local_ns=None):
1012 def timeit(self, line='', cell=None, local_ns=None):
1014 """Time execution of a Python statement or expression
1013 """Time execution of a Python statement or expression
1015
1014
1016 Usage, in line mode:
1015 Usage, in line mode:
1017 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1016 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1018 or in cell mode:
1017 or in cell mode:
1019 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1018 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1020 code
1019 code
1021 code...
1020 code...
1022
1021
1023 Time execution of a Python statement or expression using the timeit
1022 Time execution of a Python statement or expression using the timeit
1024 module. This function can be used both as a line and cell magic:
1023 module. This function can be used both as a line and cell magic:
1025
1024
1026 - In line mode you can time a single-line statement (though multiple
1025 - In line mode you can time a single-line statement (though multiple
1027 ones can be chained with using semicolons).
1026 ones can be chained with using semicolons).
1028
1027
1029 - In cell mode, the statement in the first line is used as setup code
1028 - In cell mode, the statement in the first line is used as setup code
1030 (executed but not timed) and the body of the cell is timed. The cell
1029 (executed but not timed) and the body of the cell is timed. The cell
1031 body has access to any variables created in the setup code.
1030 body has access to any variables created in the setup code.
1032
1031
1033 Options:
1032 Options:
1034 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1033 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1035 provided, <N> is determined so as to get sufficient accuracy.
1034 provided, <N> is determined so as to get sufficient accuracy.
1036
1035
1037 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1036 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1038 best result.
1037 best result.
1039 Default: 7
1038 Default: 7
1040
1039
1041 -t: use time.time to measure the time, which is the default on Unix.
1040 -t: use time.time to measure the time, which is the default on Unix.
1042 This function measures wall time.
1041 This function measures wall time.
1043
1042
1044 -c: use time.clock to measure the time, which is the default on
1043 -c: use time.clock to measure the time, which is the default on
1045 Windows and measures wall time. On Unix, resource.getrusage is used
1044 Windows and measures wall time. On Unix, resource.getrusage is used
1046 instead and returns the CPU user time.
1045 instead and returns the CPU user time.
1047
1046
1048 -p<P>: use a precision of <P> digits to display the timing result.
1047 -p<P>: use a precision of <P> digits to display the timing result.
1049 Default: 3
1048 Default: 3
1050
1049
1051 -q: Quiet, do not print result.
1050 -q: Quiet, do not print result.
1052
1051
1053 -o: return a TimeitResult that can be stored in a variable to inspect
1052 -o: return a TimeitResult that can be stored in a variable to inspect
1054 the result in more details.
1053 the result in more details.
1055
1054
1056 .. versionchanged:: 7.3
1055 .. versionchanged:: 7.3
1057 User variables are no longer expanded,
1056 User variables are no longer expanded,
1058 the magic line is always left unmodified.
1057 the magic line is always left unmodified.
1059
1058
1060 Examples
1059 Examples
1061 --------
1060 --------
1062 ::
1061 ::
1063
1062
1064 In [1]: %timeit pass
1063 In [1]: %timeit pass
1065 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
1064 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
1066
1065
1067 In [2]: u = None
1066 In [2]: u = None
1068
1067
1069 In [3]: %timeit u is None
1068 In [3]: %timeit u is None
1070 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
1069 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
1071
1070
1072 In [4]: %timeit -r 4 u == None
1071 In [4]: %timeit -r 4 u == None
1073
1072
1074 In [5]: import time
1073 In [5]: import time
1075
1074
1076 In [6]: %timeit -n1 time.sleep(2)
1075 In [6]: %timeit -n1 time.sleep(2)
1077
1076
1078
1077
1079 The times reported by %timeit will be slightly higher than those
1078 The times reported by %timeit will be slightly higher than those
1080 reported by the timeit.py script when variables are accessed. This is
1079 reported by the timeit.py script when variables are accessed. This is
1081 due to the fact that %timeit executes the statement in the namespace
1080 due to the fact that %timeit executes the statement in the namespace
1082 of the shell, compared with timeit.py, which uses a single setup
1081 of the shell, compared with timeit.py, which uses a single setup
1083 statement to import function or create variables. Generally, the bias
1082 statement to import function or create variables. Generally, the bias
1084 does not matter as long as results from timeit.py are not mixed with
1083 does not matter as long as results from timeit.py are not mixed with
1085 those from %timeit."""
1084 those from %timeit."""
1086
1085
1087 opts, stmt = self.parse_options(
1086 opts, stmt = self.parse_options(
1088 line, "n:r:tcp:qo", posix=False, strict=False, preserve_non_opts=True
1087 line, "n:r:tcp:qo", posix=False, strict=False, preserve_non_opts=True
1089 )
1088 )
1090 if stmt == "" and cell is None:
1089 if stmt == "" and cell is None:
1091 return
1090 return
1092
1091
1093 timefunc = timeit.default_timer
1092 timefunc = timeit.default_timer
1094 number = int(getattr(opts, "n", 0))
1093 number = int(getattr(opts, "n", 0))
1095 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1094 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1096 repeat = int(getattr(opts, "r", default_repeat))
1095 repeat = int(getattr(opts, "r", default_repeat))
1097 precision = int(getattr(opts, "p", 3))
1096 precision = int(getattr(opts, "p", 3))
1098 quiet = 'q' in opts
1097 quiet = 'q' in opts
1099 return_result = 'o' in opts
1098 return_result = 'o' in opts
1100 if hasattr(opts, "t"):
1099 if hasattr(opts, "t"):
1101 timefunc = time.time
1100 timefunc = time.time
1102 if hasattr(opts, "c"):
1101 if hasattr(opts, "c"):
1103 timefunc = clock
1102 timefunc = clock
1104
1103
1105 timer = Timer(timer=timefunc)
1104 timer = Timer(timer=timefunc)
1106 # this code has tight coupling to the inner workings of timeit.Timer,
1105 # this code has tight coupling to the inner workings of timeit.Timer,
1107 # but is there a better way to achieve that the code stmt has access
1106 # but is there a better way to achieve that the code stmt has access
1108 # to the shell namespace?
1107 # to the shell namespace?
1109 transform = self.shell.transform_cell
1108 transform = self.shell.transform_cell
1110
1109
1111 if cell is None:
1110 if cell is None:
1112 # called as line magic
1111 # called as line magic
1113 ast_setup = self.shell.compile.ast_parse("pass")
1112 ast_setup = self.shell.compile.ast_parse("pass")
1114 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1113 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1115 else:
1114 else:
1116 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1115 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1117 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1116 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1118
1117
1119 ast_setup = self.shell.transform_ast(ast_setup)
1118 ast_setup = self.shell.transform_ast(ast_setup)
1120 ast_stmt = self.shell.transform_ast(ast_stmt)
1119 ast_stmt = self.shell.transform_ast(ast_stmt)
1121
1120
1122 # Check that these compile to valid Python code *outside* the timer func
1121 # Check that these compile to valid Python code *outside* the timer func
1123 # Invalid code may become valid when put inside the function & loop,
1122 # Invalid code may become valid when put inside the function & loop,
1124 # which messes up error messages.
1123 # which messes up error messages.
1125 # https://github.com/ipython/ipython/issues/10636
1124 # https://github.com/ipython/ipython/issues/10636
1126 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1125 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1127 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1126 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1128
1127
1129 # This codestring is taken from timeit.template - we fill it in as an
1128 # This codestring is taken from timeit.template - we fill it in as an
1130 # AST, so that we can apply our AST transformations to the user code
1129 # AST, so that we can apply our AST transformations to the user code
1131 # without affecting the timing code.
1130 # without affecting the timing code.
1132 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1131 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1133 ' setup\n'
1132 ' setup\n'
1134 ' _t0 = _timer()\n'
1133 ' _t0 = _timer()\n'
1135 ' for _i in _it:\n'
1134 ' for _i in _it:\n'
1136 ' stmt\n'
1135 ' stmt\n'
1137 ' _t1 = _timer()\n'
1136 ' _t1 = _timer()\n'
1138 ' return _t1 - _t0\n')
1137 ' return _t1 - _t0\n')
1139
1138
1140 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1139 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1141 timeit_ast = ast.fix_missing_locations(timeit_ast)
1140 timeit_ast = ast.fix_missing_locations(timeit_ast)
1142
1141
1143 # Track compilation time so it can be reported if too long
1142 # Track compilation time so it can be reported if too long
1144 # Minimum time above which compilation time will be reported
1143 # Minimum time above which compilation time will be reported
1145 tc_min = 0.1
1144 tc_min = 0.1
1146
1145
1147 t0 = clock()
1146 t0 = clock()
1148 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1147 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1149 tc = clock()-t0
1148 tc = clock()-t0
1150
1149
1151 ns = {}
1150 ns = {}
1152 glob = self.shell.user_ns
1151 glob = self.shell.user_ns
1153 # handles global vars with same name as local vars. We store them in conflict_globs.
1152 # handles global vars with same name as local vars. We store them in conflict_globs.
1154 conflict_globs = {}
1153 conflict_globs = {}
1155 if local_ns and cell is None:
1154 if local_ns and cell is None:
1156 for var_name, var_val in glob.items():
1155 for var_name, var_val in glob.items():
1157 if var_name in local_ns:
1156 if var_name in local_ns:
1158 conflict_globs[var_name] = var_val
1157 conflict_globs[var_name] = var_val
1159 glob.update(local_ns)
1158 glob.update(local_ns)
1160
1159
1161 exec(code, glob, ns)
1160 exec(code, glob, ns)
1162 timer.inner = ns["inner"]
1161 timer.inner = ns["inner"]
1163
1162
1164 # This is used to check if there is a huge difference between the
1163 # This is used to check if there is a huge difference between the
1165 # best and worst timings.
1164 # best and worst timings.
1166 # Issue: https://github.com/ipython/ipython/issues/6471
1165 # Issue: https://github.com/ipython/ipython/issues/6471
1167 if number == 0:
1166 if number == 0:
1168 # determine number so that 0.2 <= total time < 2.0
1167 # determine number so that 0.2 <= total time < 2.0
1169 for index in range(0, 10):
1168 for index in range(0, 10):
1170 number = 10 ** index
1169 number = 10 ** index
1171 time_number = timer.timeit(number)
1170 time_number = timer.timeit(number)
1172 if time_number >= 0.2:
1171 if time_number >= 0.2:
1173 break
1172 break
1174
1173
1175 all_runs = timer.repeat(repeat, number)
1174 all_runs = timer.repeat(repeat, number)
1176 best = min(all_runs) / number
1175 best = min(all_runs) / number
1177 worst = max(all_runs) / number
1176 worst = max(all_runs) / number
1178 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1177 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1179
1178
1180 # Restore global vars from conflict_globs
1179 # Restore global vars from conflict_globs
1181 if conflict_globs:
1180 if conflict_globs:
1182 glob.update(conflict_globs)
1181 glob.update(conflict_globs)
1183
1182
1184 if not quiet :
1183 if not quiet :
1185 # Check best timing is greater than zero to avoid a
1184 # Check best timing is greater than zero to avoid a
1186 # ZeroDivisionError.
1185 # ZeroDivisionError.
1187 # In cases where the slowest timing is lesser than a microsecond
1186 # In cases where the slowest timing is lesser than a microsecond
1188 # we assume that it does not really matter if the fastest
1187 # we assume that it does not really matter if the fastest
1189 # timing is 4 times faster than the slowest timing or not.
1188 # timing is 4 times faster than the slowest timing or not.
1190 if worst > 4 * best and best > 0 and worst > 1e-6:
1189 if worst > 4 * best and best > 0 and worst > 1e-6:
1191 print("The slowest run took %0.2f times longer than the "
1190 print("The slowest run took %0.2f times longer than the "
1192 "fastest. This could mean that an intermediate result "
1191 "fastest. This could mean that an intermediate result "
1193 "is being cached." % (worst / best))
1192 "is being cached." % (worst / best))
1194
1193
1195 print( timeit_result )
1194 print( timeit_result )
1196
1195
1197 if tc > tc_min:
1196 if tc > tc_min:
1198 print("Compiler time: %.2f s" % tc)
1197 print("Compiler time: %.2f s" % tc)
1199 if return_result:
1198 if return_result:
1200 return timeit_result
1199 return timeit_result
1201
1200
1202 @skip_doctest
1201 @skip_doctest
1203 @no_var_expand
1202 @no_var_expand
1204 @needs_local_scope
1203 @needs_local_scope
1205 @line_cell_magic
1204 @line_cell_magic
1206 def time(self,line='', cell=None, local_ns=None):
1205 def time(self,line='', cell=None, local_ns=None):
1207 """Time execution of a Python statement or expression.
1206 """Time execution of a Python statement or expression.
1208
1207
1209 The CPU and wall clock times are printed, and the value of the
1208 The CPU and wall clock times are printed, and the value of the
1210 expression (if any) is returned. Note that under Win32, system time
1209 expression (if any) is returned. Note that under Win32, system time
1211 is always reported as 0, since it can not be measured.
1210 is always reported as 0, since it can not be measured.
1212
1211
1213 This function can be used both as a line and cell magic:
1212 This function can be used both as a line and cell magic:
1214
1213
1215 - In line mode you can time a single-line statement (though multiple
1214 - In line mode you can time a single-line statement (though multiple
1216 ones can be chained with using semicolons).
1215 ones can be chained with using semicolons).
1217
1216
1218 - In cell mode, you can time the cell body (a directly
1217 - In cell mode, you can time the cell body (a directly
1219 following statement raises an error).
1218 following statement raises an error).
1220
1219
1221 This function provides very basic timing functionality. Use the timeit
1220 This function provides very basic timing functionality. Use the timeit
1222 magic for more control over the measurement.
1221 magic for more control over the measurement.
1223
1222
1224 .. versionchanged:: 7.3
1223 .. versionchanged:: 7.3
1225 User variables are no longer expanded,
1224 User variables are no longer expanded,
1226 the magic line is always left unmodified.
1225 the magic line is always left unmodified.
1227
1226
1228 Examples
1227 Examples
1229 --------
1228 --------
1230 ::
1229 ::
1231
1230
1232 In [1]: %time 2**128
1231 In [1]: %time 2**128
1233 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1232 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1234 Wall time: 0.00
1233 Wall time: 0.00
1235 Out[1]: 340282366920938463463374607431768211456L
1234 Out[1]: 340282366920938463463374607431768211456L
1236
1235
1237 In [2]: n = 1000000
1236 In [2]: n = 1000000
1238
1237
1239 In [3]: %time sum(range(n))
1238 In [3]: %time sum(range(n))
1240 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1239 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1241 Wall time: 1.37
1240 Wall time: 1.37
1242 Out[3]: 499999500000L
1241 Out[3]: 499999500000L
1243
1242
1244 In [4]: %time print 'hello world'
1243 In [4]: %time print 'hello world'
1245 hello world
1244 hello world
1246 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
1247 Wall time: 0.00
1246 Wall time: 0.00
1248
1247
1249
1248
1250 .. note::
1249 .. note::
1251 The time needed by Python to compile the given expression will be
1250 The time needed by Python to compile the given expression will be
1252 reported if it is more than 0.1s.
1251 reported if it is more than 0.1s.
1253
1252
1254 In the example below, the actual exponentiation is done by Python
1253 In the example below, the actual exponentiation is done by Python
1255 at compilation time, so while the expression can take a noticeable
1254 at compilation time, so while the expression can take a noticeable
1256 amount of time to compute, that time is purely due to the
1255 amount of time to compute, that time is purely due to the
1257 compilation::
1256 compilation::
1258
1257
1259 In [5]: %time 3**9999;
1258 In [5]: %time 3**9999;
1260 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1259 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1261 Wall time: 0.00 s
1260 Wall time: 0.00 s
1262
1261
1263 In [6]: %time 3**999999;
1262 In [6]: %time 3**999999;
1264 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1263 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1265 Wall time: 0.00 s
1264 Wall time: 0.00 s
1266 Compiler : 0.78 s
1265 Compiler : 0.78 s
1267 """
1266 """
1268 # fail immediately if the given expression can't be compiled
1267 # fail immediately if the given expression can't be compiled
1269
1268
1270 if line and cell:
1269 if line and cell:
1271 raise UsageError("Can't use statement directly after '%%time'!")
1270 raise UsageError("Can't use statement directly after '%%time'!")
1272
1271
1273 if cell:
1272 if cell:
1274 expr = self.shell.transform_cell(cell)
1273 expr = self.shell.transform_cell(cell)
1275 else:
1274 else:
1276 expr = self.shell.transform_cell(line)
1275 expr = self.shell.transform_cell(line)
1277
1276
1278 # Minimum time above which parse time will be reported
1277 # Minimum time above which parse time will be reported
1279 tp_min = 0.1
1278 tp_min = 0.1
1280
1279
1281 t0 = clock()
1280 t0 = clock()
1282 expr_ast = self.shell.compile.ast_parse(expr)
1281 expr_ast = self.shell.compile.ast_parse(expr)
1283 tp = clock()-t0
1282 tp = clock()-t0
1284
1283
1285 # Apply AST transformations
1284 # Apply AST transformations
1286 expr_ast = self.shell.transform_ast(expr_ast)
1285 expr_ast = self.shell.transform_ast(expr_ast)
1287
1286
1288 # Minimum time above which compilation time will be reported
1287 # Minimum time above which compilation time will be reported
1289 tc_min = 0.1
1288 tc_min = 0.1
1290
1289
1291 expr_val=None
1290 expr_val=None
1292 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1291 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1293 mode = 'eval'
1292 mode = 'eval'
1294 source = '<timed eval>'
1293 source = '<timed eval>'
1295 expr_ast = ast.Expression(expr_ast.body[0].value)
1294 expr_ast = ast.Expression(expr_ast.body[0].value)
1296 else:
1295 else:
1297 mode = 'exec'
1296 mode = 'exec'
1298 source = '<timed exec>'
1297 source = '<timed exec>'
1299 # multi-line %%time case
1298 # multi-line %%time case
1300 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1299 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1301 expr_val= expr_ast.body[-1]
1300 expr_val= expr_ast.body[-1]
1302 expr_ast = expr_ast.body[:-1]
1301 expr_ast = expr_ast.body[:-1]
1303 expr_ast = Module(expr_ast, [])
1302 expr_ast = Module(expr_ast, [])
1304 expr_val = ast.Expression(expr_val.value)
1303 expr_val = ast.Expression(expr_val.value)
1305
1304
1306 t0 = clock()
1305 t0 = clock()
1307 code = self.shell.compile(expr_ast, source, mode)
1306 code = self.shell.compile(expr_ast, source, mode)
1308 tc = clock()-t0
1307 tc = clock()-t0
1309
1308
1310 # skew measurement as little as possible
1309 # skew measurement as little as possible
1311 glob = self.shell.user_ns
1310 glob = self.shell.user_ns
1312 wtime = time.time
1311 wtime = time.time
1313 # time execution
1312 # time execution
1314 wall_st = wtime()
1313 wall_st = wtime()
1315 if mode=='eval':
1314 if mode=='eval':
1316 st = clock2()
1315 st = clock2()
1317 try:
1316 try:
1318 out = eval(code, glob, local_ns)
1317 out = eval(code, glob, local_ns)
1319 except:
1318 except:
1320 self.shell.showtraceback()
1319 self.shell.showtraceback()
1321 return
1320 return
1322 end = clock2()
1321 end = clock2()
1323 else:
1322 else:
1324 st = clock2()
1323 st = clock2()
1325 try:
1324 try:
1326 exec(code, glob, local_ns)
1325 exec(code, glob, local_ns)
1327 out=None
1326 out=None
1328 # multi-line %%time case
1327 # multi-line %%time case
1329 if expr_val is not None:
1328 if expr_val is not None:
1330 code_2 = self.shell.compile(expr_val, source, 'eval')
1329 code_2 = self.shell.compile(expr_val, source, 'eval')
1331 out = eval(code_2, glob, local_ns)
1330 out = eval(code_2, glob, local_ns)
1332 except:
1331 except:
1333 self.shell.showtraceback()
1332 self.shell.showtraceback()
1334 return
1333 return
1335 end = clock2()
1334 end = clock2()
1336
1335
1337 wall_end = wtime()
1336 wall_end = wtime()
1338 # Compute actual times and report
1337 # Compute actual times and report
1339 wall_time = wall_end-wall_st
1338 wall_time = wall_end-wall_st
1340 cpu_user = end[0]-st[0]
1339 cpu_user = end[0]-st[0]
1341 cpu_sys = end[1]-st[1]
1340 cpu_sys = end[1]-st[1]
1342 cpu_tot = cpu_user+cpu_sys
1341 cpu_tot = cpu_user+cpu_sys
1343 # On windows cpu_sys is always zero, so no new information to the next print
1342 # On windows cpu_sys is always zero, so no new information to the next print
1344 if sys.platform != 'win32':
1343 if sys.platform != 'win32':
1345 print("CPU times: user %s, sys: %s, total: %s" % \
1344 print("CPU times: user %s, sys: %s, total: %s" % \
1346 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1345 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1347 print("Wall time: %s" % _format_time(wall_time))
1346 print("Wall time: %s" % _format_time(wall_time))
1348 if tc > tc_min:
1347 if tc > tc_min:
1349 print("Compiler : %s" % _format_time(tc))
1348 print("Compiler : %s" % _format_time(tc))
1350 if tp > tp_min:
1349 if tp > tp_min:
1351 print("Parser : %s" % _format_time(tp))
1350 print("Parser : %s" % _format_time(tp))
1352 return out
1351 return out
1353
1352
1354 @skip_doctest
1353 @skip_doctest
1355 @line_magic
1354 @line_magic
1356 def macro(self, parameter_s=''):
1355 def macro(self, parameter_s=''):
1357 """Define a macro for future re-execution. It accepts ranges of history,
1356 """Define a macro for future re-execution. It accepts ranges of history,
1358 filenames or string objects.
1357 filenames or string objects.
1359
1358
1360 Usage:\\
1359 Usage:\\
1361 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1360 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1362
1361
1363 Options:
1362 Options:
1364
1363
1365 -r: use 'raw' input. By default, the 'processed' history is used,
1364 -r: use 'raw' input. By default, the 'processed' history is used,
1366 so that magics are loaded in their transformed version to valid
1365 so that magics are loaded in their transformed version to valid
1367 Python. If this option is given, the raw input as typed at the
1366 Python. If this option is given, the raw input as typed at the
1368 command line is used instead.
1367 command line is used instead.
1369
1368
1370 -q: quiet macro definition. By default, a tag line is printed
1369 -q: quiet macro definition. By default, a tag line is printed
1371 to indicate the macro has been created, and then the contents of
1370 to indicate the macro has been created, and then the contents of
1372 the macro are printed. If this option is given, then no printout
1371 the macro are printed. If this option is given, then no printout
1373 is produced once the macro is created.
1372 is produced once the macro is created.
1374
1373
1375 This will define a global variable called `name` which is a string
1374 This will define a global variable called `name` which is a string
1376 made of joining the slices and lines you specify (n1,n2,... numbers
1375 made of joining the slices and lines you specify (n1,n2,... numbers
1377 above) from your input history into a single string. This variable
1376 above) from your input history into a single string. This variable
1378 acts like an automatic function which re-executes those lines as if
1377 acts like an automatic function which re-executes those lines as if
1379 you had typed them. You just type 'name' at the prompt and the code
1378 you had typed them. You just type 'name' at the prompt and the code
1380 executes.
1379 executes.
1381
1380
1382 The syntax for indicating input ranges is described in %history.
1381 The syntax for indicating input ranges is described in %history.
1383
1382
1384 Note: as a 'hidden' feature, you can also use traditional python slice
1383 Note: as a 'hidden' feature, you can also use traditional python slice
1385 notation, where N:M means numbers N through M-1.
1384 notation, where N:M means numbers N through M-1.
1386
1385
1387 For example, if your history contains (print using %hist -n )::
1386 For example, if your history contains (print using %hist -n )::
1388
1387
1389 44: x=1
1388 44: x=1
1390 45: y=3
1389 45: y=3
1391 46: z=x+y
1390 46: z=x+y
1392 47: print x
1391 47: print x
1393 48: a=5
1392 48: a=5
1394 49: print 'x',x,'y',y
1393 49: print 'x',x,'y',y
1395
1394
1396 you can create a macro with lines 44 through 47 (included) and line 49
1395 you can create a macro with lines 44 through 47 (included) and line 49
1397 called my_macro with::
1396 called my_macro with::
1398
1397
1399 In [55]: %macro my_macro 44-47 49
1398 In [55]: %macro my_macro 44-47 49
1400
1399
1401 Now, typing `my_macro` (without quotes) will re-execute all this code
1400 Now, typing `my_macro` (without quotes) will re-execute all this code
1402 in one pass.
1401 in one pass.
1403
1402
1404 You don't need to give the line-numbers in order, and any given line
1403 You don't need to give the line-numbers in order, and any given line
1405 number can appear multiple times. You can assemble macros with any
1404 number can appear multiple times. You can assemble macros with any
1406 lines from your input history in any order.
1405 lines from your input history in any order.
1407
1406
1408 The macro is a simple object which holds its value in an attribute,
1407 The macro is a simple object which holds its value in an attribute,
1409 but IPython's display system checks for macros and executes them as
1408 but IPython's display system checks for macros and executes them as
1410 code instead of printing them when you type their name.
1409 code instead of printing them when you type their name.
1411
1410
1412 You can view a macro's contents by explicitly printing it with::
1411 You can view a macro's contents by explicitly printing it with::
1413
1412
1414 print macro_name
1413 print macro_name
1415
1414
1416 """
1415 """
1417 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1416 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1418 if not args: # List existing macros
1417 if not args: # List existing macros
1419 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1418 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1420 if len(args) == 1:
1419 if len(args) == 1:
1421 raise UsageError(
1420 raise UsageError(
1422 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1421 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1423 name, codefrom = args[0], " ".join(args[1:])
1422 name, codefrom = args[0], " ".join(args[1:])
1424
1423
1425 #print 'rng',ranges # dbg
1424 #print 'rng',ranges # dbg
1426 try:
1425 try:
1427 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1426 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1428 except (ValueError, TypeError) as e:
1427 except (ValueError, TypeError) as e:
1429 print(e.args[0])
1428 print(e.args[0])
1430 return
1429 return
1431 macro = Macro(lines)
1430 macro = Macro(lines)
1432 self.shell.define_macro(name, macro)
1431 self.shell.define_macro(name, macro)
1433 if not ( 'q' in opts) :
1432 if not ( 'q' in opts) :
1434 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1433 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1435 print('=== Macro contents: ===')
1434 print('=== Macro contents: ===')
1436 print(macro, end=' ')
1435 print(macro, end=' ')
1437
1436
1438 @magic_arguments.magic_arguments()
1437 @magic_arguments.magic_arguments()
1439 @magic_arguments.argument('output', type=str, default='', nargs='?',
1438 @magic_arguments.argument('output', type=str, default='', nargs='?',
1440 help="""The name of the variable in which to store output.
1439 help="""The name of the variable in which to store output.
1441 This is a utils.io.CapturedIO object with stdout/err attributes
1440 This is a utils.io.CapturedIO object with stdout/err attributes
1442 for the text of the captured output.
1441 for the text of the captured output.
1443
1442
1444 CapturedOutput also has a show() method for displaying the output,
1443 CapturedOutput also has a show() method for displaying the output,
1445 and __call__ as well, so you can use that to quickly display the
1444 and __call__ as well, so you can use that to quickly display the
1446 output.
1445 output.
1447
1446
1448 If unspecified, captured output is discarded.
1447 If unspecified, captured output is discarded.
1449 """
1448 """
1450 )
1449 )
1451 @magic_arguments.argument('--no-stderr', action="store_true",
1450 @magic_arguments.argument('--no-stderr', action="store_true",
1452 help="""Don't capture stderr."""
1451 help="""Don't capture stderr."""
1453 )
1452 )
1454 @magic_arguments.argument('--no-stdout', action="store_true",
1453 @magic_arguments.argument('--no-stdout', action="store_true",
1455 help="""Don't capture stdout."""
1454 help="""Don't capture stdout."""
1456 )
1455 )
1457 @magic_arguments.argument('--no-display', action="store_true",
1456 @magic_arguments.argument('--no-display', action="store_true",
1458 help="""Don't capture IPython's rich display."""
1457 help="""Don't capture IPython's rich display."""
1459 )
1458 )
1460 @cell_magic
1459 @cell_magic
1461 def capture(self, line, cell):
1460 def capture(self, line, cell):
1462 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1461 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1463 args = magic_arguments.parse_argstring(self.capture, line)
1462 args = magic_arguments.parse_argstring(self.capture, line)
1464 out = not args.no_stdout
1463 out = not args.no_stdout
1465 err = not args.no_stderr
1464 err = not args.no_stderr
1466 disp = not args.no_display
1465 disp = not args.no_display
1467 with capture_output(out, err, disp) as io:
1466 with capture_output(out, err, disp) as io:
1468 self.shell.run_cell(cell)
1467 self.shell.run_cell(cell)
1469 if args.output:
1468 if args.output:
1470 self.shell.user_ns[args.output] = io
1469 self.shell.user_ns[args.output] = io
1471
1470
1472 def parse_breakpoint(text, current_file):
1471 def parse_breakpoint(text, current_file):
1473 '''Returns (file, line) for file:line and (current_file, line) for line'''
1472 '''Returns (file, line) for file:line and (current_file, line) for line'''
1474 colon = text.find(':')
1473 colon = text.find(':')
1475 if colon == -1:
1474 if colon == -1:
1476 return current_file, int(text)
1475 return current_file, int(text)
1477 else:
1476 else:
1478 return text[:colon], int(text[colon+1:])
1477 return text[:colon], int(text[colon+1:])
1479
1478
1480 def _format_time(timespan, precision=3):
1479 def _format_time(timespan, precision=3):
1481 """Formats the timespan in a human readable form"""
1480 """Formats the timespan in a human readable form"""
1482
1481
1483 if timespan >= 60.0:
1482 if timespan >= 60.0:
1484 # we have more than a minute, format that in a human readable form
1483 # we have more than a minute, format that in a human readable form
1485 # Idea from http://snipplr.com/view/5713/
1484 # Idea from http://snipplr.com/view/5713/
1486 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1485 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1487 time = []
1486 time = []
1488 leftover = timespan
1487 leftover = timespan
1489 for suffix, length in parts:
1488 for suffix, length in parts:
1490 value = int(leftover / length)
1489 value = int(leftover / length)
1491 if value > 0:
1490 if value > 0:
1492 leftover = leftover % length
1491 leftover = leftover % length
1493 time.append(u'%s%s' % (str(value), suffix))
1492 time.append(u'%s%s' % (str(value), suffix))
1494 if leftover < 1:
1493 if leftover < 1:
1495 break
1494 break
1496 return " ".join(time)
1495 return " ".join(time)
1497
1496
1498
1497
1499 # Unfortunately the unicode 'micro' symbol can cause problems in
1498 # Unfortunately the unicode 'micro' symbol can cause problems in
1500 # certain terminals.
1499 # certain terminals.
1501 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1500 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1502 # Try to prevent crashes by being more secure than it needs to
1501 # Try to prevent crashes by being more secure than it needs to
1503 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1502 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1504 units = [u"s", u"ms",u'us',"ns"] # the save value
1503 units = [u"s", u"ms",u'us',"ns"] # the save value
1505 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1504 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1506 try:
1505 try:
1507 u'\xb5'.encode(sys.stdout.encoding)
1506 u'\xb5'.encode(sys.stdout.encoding)
1508 units = [u"s", u"ms",u'\xb5s',"ns"]
1507 units = [u"s", u"ms",u'\xb5s',"ns"]
1509 except:
1508 except:
1510 pass
1509 pass
1511 scaling = [1, 1e3, 1e6, 1e9]
1510 scaling = [1, 1e3, 1e6, 1e9]
1512
1511
1513 if timespan > 0.0:
1512 if timespan > 0.0:
1514 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1513 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1515 else:
1514 else:
1516 order = 3
1515 order = 3
1517 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1516 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,859 +1,856 b''
1 """Implementation of magic functions for interaction with the OS.
1 """Implementation of magic functions for interaction with the OS.
2
2
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 builtin.
4 builtin.
5 """
5 """
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import io
9 import io
10 import os
10 import os
11 import re
11 import re
12 import sys
12 import sys
13 from pprint import pformat
13 from pprint import pformat
14
14
15 from IPython.core import magic_arguments
15 from IPython.core import magic_arguments
16 from IPython.core import oinspect
16 from IPython.core import oinspect
17 from IPython.core import page
17 from IPython.core import page
18 from IPython.core.alias import AliasError, Alias
18 from IPython.core.alias import AliasError, Alias
19 from IPython.core.error import UsageError
19 from IPython.core.error import UsageError
20 from IPython.core.magic import (
20 from IPython.core.magic import (
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
22 )
22 )
23 from IPython.testing.skipdoctest import skip_doctest
23 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.utils.openpy import source_to_unicode
24 from IPython.utils.openpy import source_to_unicode
25 from IPython.utils.process import abbrev_cwd
25 from IPython.utils.process import abbrev_cwd
26 from IPython.utils.terminal import set_term_title
26 from IPython.utils.terminal import set_term_title
27 from traitlets import Bool
27 from traitlets import Bool
28 from warnings import warn
28 from warnings import warn
29
29
30
30
31 @magics_class
31 @magics_class
32 class OSMagics(Magics):
32 class OSMagics(Magics):
33 """Magics to interact with the underlying OS (shell-type functionality).
33 """Magics to interact with the underlying OS (shell-type functionality).
34 """
34 """
35
35
36 cd_force_quiet = Bool(False,
36 cd_force_quiet = Bool(False,
37 help="Force %cd magic to be quiet even if -q is not passed."
37 help="Force %cd magic to be quiet even if -q is not passed."
38 ).tag(config=True)
38 ).tag(config=True)
39
39
40 def __init__(self, shell=None, **kwargs):
40 def __init__(self, shell=None, **kwargs):
41
41
42 # Now define isexec in a cross platform manner.
42 # Now define isexec in a cross platform manner.
43 self.is_posix = False
43 self.is_posix = False
44 self.execre = None
44 self.execre = None
45 if os.name == 'posix':
45 if os.name == 'posix':
46 self.is_posix = True
46 self.is_posix = True
47 else:
47 else:
48 try:
48 try:
49 winext = os.environ['pathext'].replace(';','|').replace('.','')
49 winext = os.environ['pathext'].replace(';','|').replace('.','')
50 except KeyError:
50 except KeyError:
51 winext = 'exe|com|bat|py'
51 winext = 'exe|com|bat|py'
52 try:
52 try:
53 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
53 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
54 except re.error:
54 except re.error:
55 warn("Seems like your pathext environmental "
55 warn("Seems like your pathext environmental "
56 "variable is malformed. Please check it to "
56 "variable is malformed. Please check it to "
57 "enable a proper handle of file extensions "
57 "enable a proper handle of file extensions "
58 "managed for your system")
58 "managed for your system")
59 winext = 'exe|com|bat|py'
59 winext = 'exe|com|bat|py'
60 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
60 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
61
61
62 # call up the chain
62 # call up the chain
63 super().__init__(shell=shell, **kwargs)
63 super().__init__(shell=shell, **kwargs)
64
64
65
65
66 @skip_doctest
67 def _isexec_POSIX(self, file):
66 def _isexec_POSIX(self, file):
68 """
67 """
69 Test for executable on a POSIX system
68 Test for executable on a POSIX system
70 """
69 """
71 if os.access(file.path, os.X_OK):
70 if os.access(file.path, os.X_OK):
72 # will fail on maxOS if access is not X_OK
71 # will fail on maxOS if access is not X_OK
73 return file.is_file()
72 return file.is_file()
74 return False
73 return False
75
74
76
75
77
76
78 @skip_doctest
79 def _isexec_WIN(self, file):
77 def _isexec_WIN(self, file):
80 """
78 """
81 Test for executable file on non POSIX system
79 Test for executable file on non POSIX system
82 """
80 """
83 return file.is_file() and self.execre.match(file.name) is not None
81 return file.is_file() and self.execre.match(file.name) is not None
84
82
85 @skip_doctest
86 def isexec(self, file):
83 def isexec(self, file):
87 """
84 """
88 Test for executable file on non POSIX system
85 Test for executable file on non POSIX system
89 """
86 """
90 if self.is_posix:
87 if self.is_posix:
91 return self._isexec_POSIX(file)
88 return self._isexec_POSIX(file)
92 else:
89 else:
93 return self._isexec_WIN(file)
90 return self._isexec_WIN(file)
94
91
95
92
96 @skip_doctest
93 @skip_doctest
97 @line_magic
94 @line_magic
98 def alias(self, parameter_s=''):
95 def alias(self, parameter_s=''):
99 """Define an alias for a system command.
96 """Define an alias for a system command.
100
97
101 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
98 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
102
99
103 Then, typing 'alias_name params' will execute the system command 'cmd
100 Then, typing 'alias_name params' will execute the system command 'cmd
104 params' (from your underlying operating system).
101 params' (from your underlying operating system).
105
102
106 Aliases have lower precedence than magic functions and Python normal
103 Aliases have lower precedence than magic functions and Python normal
107 variables, so if 'foo' is both a Python variable and an alias, the
104 variables, so if 'foo' is both a Python variable and an alias, the
108 alias can not be executed until 'del foo' removes the Python variable.
105 alias can not be executed until 'del foo' removes the Python variable.
109
106
110 You can use the %l specifier in an alias definition to represent the
107 You can use the %l specifier in an alias definition to represent the
111 whole line when the alias is called. For example::
108 whole line when the alias is called. For example::
112
109
113 In [2]: alias bracket echo "Input in brackets: <%l>"
110 In [2]: alias bracket echo "Input in brackets: <%l>"
114 In [3]: bracket hello world
111 In [3]: bracket hello world
115 Input in brackets: <hello world>
112 Input in brackets: <hello world>
116
113
117 You can also define aliases with parameters using %s specifiers (one
114 You can also define aliases with parameters using %s specifiers (one
118 per parameter)::
115 per parameter)::
119
116
120 In [1]: alias parts echo first %s second %s
117 In [1]: alias parts echo first %s second %s
121 In [2]: %parts A B
118 In [2]: %parts A B
122 first A second B
119 first A second B
123 In [3]: %parts A
120 In [3]: %parts A
124 Incorrect number of arguments: 2 expected.
121 Incorrect number of arguments: 2 expected.
125 parts is an alias to: 'echo first %s second %s'
122 parts is an alias to: 'echo first %s second %s'
126
123
127 Note that %l and %s are mutually exclusive. You can only use one or
124 Note that %l and %s are mutually exclusive. You can only use one or
128 the other in your aliases.
125 the other in your aliases.
129
126
130 Aliases expand Python variables just like system calls using ! or !!
127 Aliases expand Python variables just like system calls using ! or !!
131 do: all expressions prefixed with '$' get expanded. For details of
128 do: all expressions prefixed with '$' get expanded. For details of
132 the semantic rules, see PEP-215:
129 the semantic rules, see PEP-215:
133 http://www.python.org/peps/pep-0215.html. This is the library used by
130 http://www.python.org/peps/pep-0215.html. This is the library used by
134 IPython for variable expansion. If you want to access a true shell
131 IPython for variable expansion. If you want to access a true shell
135 variable, an extra $ is necessary to prevent its expansion by
132 variable, an extra $ is necessary to prevent its expansion by
136 IPython::
133 IPython::
137
134
138 In [6]: alias show echo
135 In [6]: alias show echo
139 In [7]: PATH='A Python string'
136 In [7]: PATH='A Python string'
140 In [8]: show $PATH
137 In [8]: show $PATH
141 A Python string
138 A Python string
142 In [9]: show $$PATH
139 In [9]: show $$PATH
143 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
140 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
144
141
145 You can use the alias facility to access all of $PATH. See the %rehashx
142 You can use the alias facility to access all of $PATH. See the %rehashx
146 function, which automatically creates aliases for the contents of your
143 function, which automatically creates aliases for the contents of your
147 $PATH.
144 $PATH.
148
145
149 If called with no parameters, %alias prints the current alias table
146 If called with no parameters, %alias prints the current alias table
150 for your system. For posix systems, the default aliases are 'cat',
147 for your system. For posix systems, the default aliases are 'cat',
151 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
148 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
152 aliases are added. For windows-based systems, the default aliases are
149 aliases are added. For windows-based systems, the default aliases are
153 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
150 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
154
151
155 You can see the definition of alias by adding a question mark in the
152 You can see the definition of alias by adding a question mark in the
156 end::
153 end::
157
154
158 In [1]: cat?
155 In [1]: cat?
159 Repr: <alias cat for 'cat'>"""
156 Repr: <alias cat for 'cat'>"""
160
157
161 par = parameter_s.strip()
158 par = parameter_s.strip()
162 if not par:
159 if not par:
163 aliases = sorted(self.shell.alias_manager.aliases)
160 aliases = sorted(self.shell.alias_manager.aliases)
164 # stored = self.shell.db.get('stored_aliases', {} )
161 # stored = self.shell.db.get('stored_aliases', {} )
165 # for k, v in stored:
162 # for k, v in stored:
166 # atab.append(k, v[0])
163 # atab.append(k, v[0])
167
164
168 print("Total number of aliases:", len(aliases))
165 print("Total number of aliases:", len(aliases))
169 sys.stdout.flush()
166 sys.stdout.flush()
170 return aliases
167 return aliases
171
168
172 # Now try to define a new one
169 # Now try to define a new one
173 try:
170 try:
174 alias,cmd = par.split(None, 1)
171 alias,cmd = par.split(None, 1)
175 except TypeError:
172 except TypeError:
176 print(oinspect.getdoc(self.alias))
173 print(oinspect.getdoc(self.alias))
177 return
174 return
178
175
179 try:
176 try:
180 self.shell.alias_manager.define_alias(alias, cmd)
177 self.shell.alias_manager.define_alias(alias, cmd)
181 except AliasError as e:
178 except AliasError as e:
182 print(e)
179 print(e)
183 # end magic_alias
180 # end magic_alias
184
181
185 @line_magic
182 @line_magic
186 def unalias(self, parameter_s=''):
183 def unalias(self, parameter_s=''):
187 """Remove an alias"""
184 """Remove an alias"""
188
185
189 aname = parameter_s.strip()
186 aname = parameter_s.strip()
190 try:
187 try:
191 self.shell.alias_manager.undefine_alias(aname)
188 self.shell.alias_manager.undefine_alias(aname)
192 except ValueError as e:
189 except ValueError as e:
193 print(e)
190 print(e)
194 return
191 return
195
192
196 stored = self.shell.db.get('stored_aliases', {} )
193 stored = self.shell.db.get('stored_aliases', {} )
197 if aname in stored:
194 if aname in stored:
198 print("Removing %stored alias",aname)
195 print("Removing %stored alias",aname)
199 del stored[aname]
196 del stored[aname]
200 self.shell.db['stored_aliases'] = stored
197 self.shell.db['stored_aliases'] = stored
201
198
202 @line_magic
199 @line_magic
203 def rehashx(self, parameter_s=''):
200 def rehashx(self, parameter_s=''):
204 """Update the alias table with all executable files in $PATH.
201 """Update the alias table with all executable files in $PATH.
205
202
206 rehashx explicitly checks that every entry in $PATH is a file
203 rehashx explicitly checks that every entry in $PATH is a file
207 with execute access (os.X_OK).
204 with execute access (os.X_OK).
208
205
209 Under Windows, it checks executability as a match against a
206 Under Windows, it checks executability as a match against a
210 '|'-separated string of extensions, stored in the IPython config
207 '|'-separated string of extensions, stored in the IPython config
211 variable win_exec_ext. This defaults to 'exe|com|bat'.
208 variable win_exec_ext. This defaults to 'exe|com|bat'.
212
209
213 This function also resets the root module cache of module completer,
210 This function also resets the root module cache of module completer,
214 used on slow filesystems.
211 used on slow filesystems.
215 """
212 """
216 from IPython.core.alias import InvalidAliasError
213 from IPython.core.alias import InvalidAliasError
217
214
218 # for the benefit of module completer in ipy_completers.py
215 # for the benefit of module completer in ipy_completers.py
219 del self.shell.db['rootmodules_cache']
216 del self.shell.db['rootmodules_cache']
220
217
221 path = [os.path.abspath(os.path.expanduser(p)) for p in
218 path = [os.path.abspath(os.path.expanduser(p)) for p in
222 os.environ.get('PATH','').split(os.pathsep)]
219 os.environ.get('PATH','').split(os.pathsep)]
223
220
224 syscmdlist = []
221 syscmdlist = []
225 savedir = os.getcwd()
222 savedir = os.getcwd()
226
223
227 # Now walk the paths looking for executables to alias.
224 # Now walk the paths looking for executables to alias.
228 try:
225 try:
229 # write the whole loop for posix/Windows so we don't have an if in
226 # write the whole loop for posix/Windows so we don't have an if in
230 # the innermost part
227 # the innermost part
231 if self.is_posix:
228 if self.is_posix:
232 for pdir in path:
229 for pdir in path:
233 try:
230 try:
234 os.chdir(pdir)
231 os.chdir(pdir)
235 except OSError:
232 except OSError:
236 continue
233 continue
237
234
238 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
235 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
239 dirlist = os.scandir(path=pdir)
236 dirlist = os.scandir(path=pdir)
240 for ff in dirlist:
237 for ff in dirlist:
241 if self.isexec(ff):
238 if self.isexec(ff):
242 fname = ff.name
239 fname = ff.name
243 try:
240 try:
244 # Removes dots from the name since ipython
241 # Removes dots from the name since ipython
245 # will assume names with dots to be python.
242 # will assume names with dots to be python.
246 if not self.shell.alias_manager.is_alias(fname):
243 if not self.shell.alias_manager.is_alias(fname):
247 self.shell.alias_manager.define_alias(
244 self.shell.alias_manager.define_alias(
248 fname.replace('.',''), fname)
245 fname.replace('.',''), fname)
249 except InvalidAliasError:
246 except InvalidAliasError:
250 pass
247 pass
251 else:
248 else:
252 syscmdlist.append(fname)
249 syscmdlist.append(fname)
253 else:
250 else:
254 no_alias = Alias.blacklist
251 no_alias = Alias.blacklist
255 for pdir in path:
252 for pdir in path:
256 try:
253 try:
257 os.chdir(pdir)
254 os.chdir(pdir)
258 except OSError:
255 except OSError:
259 continue
256 continue
260
257
261 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
258 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
262 dirlist = os.scandir(pdir)
259 dirlist = os.scandir(pdir)
263 for ff in dirlist:
260 for ff in dirlist:
264 fname = ff.name
261 fname = ff.name
265 base, ext = os.path.splitext(fname)
262 base, ext = os.path.splitext(fname)
266 if self.isexec(ff) and base.lower() not in no_alias:
263 if self.isexec(ff) and base.lower() not in no_alias:
267 if ext.lower() == '.exe':
264 if ext.lower() == '.exe':
268 fname = base
265 fname = base
269 try:
266 try:
270 # Removes dots from the name since ipython
267 # Removes dots from the name since ipython
271 # will assume names with dots to be python.
268 # will assume names with dots to be python.
272 self.shell.alias_manager.define_alias(
269 self.shell.alias_manager.define_alias(
273 base.lower().replace('.',''), fname)
270 base.lower().replace('.',''), fname)
274 except InvalidAliasError:
271 except InvalidAliasError:
275 pass
272 pass
276 syscmdlist.append(fname)
273 syscmdlist.append(fname)
277
274
278 self.shell.db['syscmdlist'] = syscmdlist
275 self.shell.db['syscmdlist'] = syscmdlist
279 finally:
276 finally:
280 os.chdir(savedir)
277 os.chdir(savedir)
281
278
282 @skip_doctest
279 @skip_doctest
283 @line_magic
280 @line_magic
284 def pwd(self, parameter_s=''):
281 def pwd(self, parameter_s=''):
285 """Return the current working directory path.
282 """Return the current working directory path.
286
283
287 Examples
284 Examples
288 --------
285 --------
289 ::
286 ::
290
287
291 In [9]: pwd
288 In [9]: pwd
292 Out[9]: '/home/tsuser/sprint/ipython'
289 Out[9]: '/home/tsuser/sprint/ipython'
293 """
290 """
294 try:
291 try:
295 return os.getcwd()
292 return os.getcwd()
296 except FileNotFoundError as e:
293 except FileNotFoundError as e:
297 raise UsageError("CWD no longer exists - please use %cd to change directory.") from e
294 raise UsageError("CWD no longer exists - please use %cd to change directory.") from e
298
295
299 @skip_doctest
296 @skip_doctest
300 @line_magic
297 @line_magic
301 def cd(self, parameter_s=''):
298 def cd(self, parameter_s=''):
302 """Change the current working directory.
299 """Change the current working directory.
303
300
304 This command automatically maintains an internal list of directories
301 This command automatically maintains an internal list of directories
305 you visit during your IPython session, in the variable ``_dh``. The
302 you visit during your IPython session, in the variable ``_dh``. The
306 command :magic:`%dhist` shows this history nicely formatted. You can
303 command :magic:`%dhist` shows this history nicely formatted. You can
307 also do ``cd -<tab>`` to see directory history conveniently.
304 also do ``cd -<tab>`` to see directory history conveniently.
308 Usage:
305 Usage:
309
306
310 - ``cd 'dir'``: changes to directory 'dir'.
307 - ``cd 'dir'``: changes to directory 'dir'.
311 - ``cd -``: changes to the last visited directory.
308 - ``cd -``: changes to the last visited directory.
312 - ``cd -<n>``: changes to the n-th directory in the directory history.
309 - ``cd -<n>``: changes to the n-th directory in the directory history.
313 - ``cd --foo``: change to directory that matches 'foo' in history
310 - ``cd --foo``: change to directory that matches 'foo' in history
314 - ``cd -b <bookmark_name>``: jump to a bookmark set by %bookmark
311 - ``cd -b <bookmark_name>``: jump to a bookmark set by %bookmark
315 - Hitting a tab key after ``cd -b`` allows you to tab-complete
312 - Hitting a tab key after ``cd -b`` allows you to tab-complete
316 bookmark names.
313 bookmark names.
317
314
318 .. note::
315 .. note::
319 ``cd <bookmark_name>`` is enough if there is no directory
316 ``cd <bookmark_name>`` is enough if there is no directory
320 ``<bookmark_name>``, but a bookmark with the name exists.
317 ``<bookmark_name>``, but a bookmark with the name exists.
321
318
322
319
323 Options:
320 Options:
324
321
325 -q Be quiet. Do not print the working directory after the
322 -q Be quiet. Do not print the working directory after the
326 cd command is executed. By default IPython's cd
323 cd command is executed. By default IPython's cd
327 command does print this directory, since the default
324 command does print this directory, since the default
328 prompts do not display path information.
325 prompts do not display path information.
329
326
330 .. note::
327 .. note::
331 Note that ``!cd`` doesn't work for this purpose because the shell
328 Note that ``!cd`` doesn't work for this purpose because the shell
332 where ``!command`` runs is immediately discarded after executing
329 where ``!command`` runs is immediately discarded after executing
333 'command'.
330 'command'.
334
331
335
332
336 Examples
333 Examples
337 --------
334 --------
338 ::
335 ::
339
336
340 In [10]: cd parent/child
337 In [10]: cd parent/child
341 /home/tsuser/parent/child
338 /home/tsuser/parent/child
342 """
339 """
343
340
344 try:
341 try:
345 oldcwd = os.getcwd()
342 oldcwd = os.getcwd()
346 except FileNotFoundError:
343 except FileNotFoundError:
347 # Happens if the CWD has been deleted.
344 # Happens if the CWD has been deleted.
348 oldcwd = None
345 oldcwd = None
349
346
350 numcd = re.match(r'(-)(\d+)$',parameter_s)
347 numcd = re.match(r'(-)(\d+)$',parameter_s)
351 # jump in directory history by number
348 # jump in directory history by number
352 if numcd:
349 if numcd:
353 nn = int(numcd.group(2))
350 nn = int(numcd.group(2))
354 try:
351 try:
355 ps = self.shell.user_ns['_dh'][nn]
352 ps = self.shell.user_ns['_dh'][nn]
356 except IndexError:
353 except IndexError:
357 print('The requested directory does not exist in history.')
354 print('The requested directory does not exist in history.')
358 return
355 return
359 else:
356 else:
360 opts = {}
357 opts = {}
361 elif parameter_s.startswith('--'):
358 elif parameter_s.startswith('--'):
362 ps = None
359 ps = None
363 fallback = None
360 fallback = None
364 pat = parameter_s[2:]
361 pat = parameter_s[2:]
365 dh = self.shell.user_ns['_dh']
362 dh = self.shell.user_ns['_dh']
366 # first search only by basename (last component)
363 # first search only by basename (last component)
367 for ent in reversed(dh):
364 for ent in reversed(dh):
368 if pat in os.path.basename(ent) and os.path.isdir(ent):
365 if pat in os.path.basename(ent) and os.path.isdir(ent):
369 ps = ent
366 ps = ent
370 break
367 break
371
368
372 if fallback is None and pat in ent and os.path.isdir(ent):
369 if fallback is None and pat in ent and os.path.isdir(ent):
373 fallback = ent
370 fallback = ent
374
371
375 # if we have no last part match, pick the first full path match
372 # if we have no last part match, pick the first full path match
376 if ps is None:
373 if ps is None:
377 ps = fallback
374 ps = fallback
378
375
379 if ps is None:
376 if ps is None:
380 print("No matching entry in directory history")
377 print("No matching entry in directory history")
381 return
378 return
382 else:
379 else:
383 opts = {}
380 opts = {}
384
381
385
382
386 else:
383 else:
387 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
384 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
388 # jump to previous
385 # jump to previous
389 if ps == '-':
386 if ps == '-':
390 try:
387 try:
391 ps = self.shell.user_ns['_dh'][-2]
388 ps = self.shell.user_ns['_dh'][-2]
392 except IndexError as e:
389 except IndexError as e:
393 raise UsageError('%cd -: No previous directory to change to.') from e
390 raise UsageError('%cd -: No previous directory to change to.') from e
394 # jump to bookmark if needed
391 # jump to bookmark if needed
395 else:
392 else:
396 if not os.path.isdir(ps) or 'b' in opts:
393 if not os.path.isdir(ps) or 'b' in opts:
397 bkms = self.shell.db.get('bookmarks', {})
394 bkms = self.shell.db.get('bookmarks', {})
398
395
399 if ps in bkms:
396 if ps in bkms:
400 target = bkms[ps]
397 target = bkms[ps]
401 print('(bookmark:%s) -> %s' % (ps, target))
398 print('(bookmark:%s) -> %s' % (ps, target))
402 ps = target
399 ps = target
403 else:
400 else:
404 if 'b' in opts:
401 if 'b' in opts:
405 raise UsageError("Bookmark '%s' not found. "
402 raise UsageError("Bookmark '%s' not found. "
406 "Use '%%bookmark -l' to see your bookmarks." % ps)
403 "Use '%%bookmark -l' to see your bookmarks." % ps)
407
404
408 # at this point ps should point to the target dir
405 # at this point ps should point to the target dir
409 if ps:
406 if ps:
410 try:
407 try:
411 os.chdir(os.path.expanduser(ps))
408 os.chdir(os.path.expanduser(ps))
412 if hasattr(self.shell, 'term_title') and self.shell.term_title:
409 if hasattr(self.shell, 'term_title') and self.shell.term_title:
413 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
410 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
414 except OSError:
411 except OSError:
415 print(sys.exc_info()[1])
412 print(sys.exc_info()[1])
416 else:
413 else:
417 cwd = os.getcwd()
414 cwd = os.getcwd()
418 dhist = self.shell.user_ns['_dh']
415 dhist = self.shell.user_ns['_dh']
419 if oldcwd != cwd:
416 if oldcwd != cwd:
420 dhist.append(cwd)
417 dhist.append(cwd)
421 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
418 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
422
419
423 else:
420 else:
424 os.chdir(self.shell.home_dir)
421 os.chdir(self.shell.home_dir)
425 if hasattr(self.shell, 'term_title') and self.shell.term_title:
422 if hasattr(self.shell, 'term_title') and self.shell.term_title:
426 set_term_title(self.shell.term_title_format.format(cwd="~"))
423 set_term_title(self.shell.term_title_format.format(cwd="~"))
427 cwd = os.getcwd()
424 cwd = os.getcwd()
428 dhist = self.shell.user_ns['_dh']
425 dhist = self.shell.user_ns['_dh']
429
426
430 if oldcwd != cwd:
427 if oldcwd != cwd:
431 dhist.append(cwd)
428 dhist.append(cwd)
432 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
429 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
433 if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']:
430 if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']:
434 print(self.shell.user_ns['_dh'][-1])
431 print(self.shell.user_ns['_dh'][-1])
435
432
436 @line_magic
433 @line_magic
437 def env(self, parameter_s=''):
434 def env(self, parameter_s=''):
438 """Get, set, or list environment variables.
435 """Get, set, or list environment variables.
439
436
440 Usage:\\
437 Usage:\\
441
438
442 :``%env``: lists all environment variables/values
439 :``%env``: lists all environment variables/values
443 :``%env var``: get value for var
440 :``%env var``: get value for var
444 :``%env var val``: set value for var
441 :``%env var val``: set value for var
445 :``%env var=val``: set value for var
442 :``%env var=val``: set value for var
446 :``%env var=$val``: set value for var, using python expansion if possible
443 :``%env var=$val``: set value for var, using python expansion if possible
447 """
444 """
448 if parameter_s.strip():
445 if parameter_s.strip():
449 split = '=' if '=' in parameter_s else ' '
446 split = '=' if '=' in parameter_s else ' '
450 bits = parameter_s.split(split)
447 bits = parameter_s.split(split)
451 if len(bits) == 1:
448 if len(bits) == 1:
452 key = parameter_s.strip()
449 key = parameter_s.strip()
453 if key in os.environ:
450 if key in os.environ:
454 return os.environ[key]
451 return os.environ[key]
455 else:
452 else:
456 err = "Environment does not have key: {0}".format(key)
453 err = "Environment does not have key: {0}".format(key)
457 raise UsageError(err)
454 raise UsageError(err)
458 if len(bits) > 1:
455 if len(bits) > 1:
459 return self.set_env(parameter_s)
456 return self.set_env(parameter_s)
460 env = dict(os.environ)
457 env = dict(os.environ)
461 # hide likely secrets when printing the whole environment
458 # hide likely secrets when printing the whole environment
462 for key in list(env):
459 for key in list(env):
463 if any(s in key.lower() for s in ('key', 'token', 'secret')):
460 if any(s in key.lower() for s in ('key', 'token', 'secret')):
464 env[key] = '<hidden>'
461 env[key] = '<hidden>'
465
462
466 return env
463 return env
467
464
468 @line_magic
465 @line_magic
469 def set_env(self, parameter_s):
466 def set_env(self, parameter_s):
470 """Set environment variables. Assumptions are that either "val" is a
467 """Set environment variables. Assumptions are that either "val" is a
471 name in the user namespace, or val is something that evaluates to a
468 name in the user namespace, or val is something that evaluates to a
472 string.
469 string.
473
470
474 Usage:\\
471 Usage:\\
475 %set_env var val: set value for var
472 %set_env var val: set value for var
476 %set_env var=val: set value for var
473 %set_env var=val: set value for var
477 %set_env var=$val: set value for var, using python expansion if possible
474 %set_env var=$val: set value for var, using python expansion if possible
478 """
475 """
479 split = '=' if '=' in parameter_s else ' '
476 split = '=' if '=' in parameter_s else ' '
480 bits = parameter_s.split(split, 1)
477 bits = parameter_s.split(split, 1)
481 if not parameter_s.strip() or len(bits)<2:
478 if not parameter_s.strip() or len(bits)<2:
482 raise UsageError("usage is 'set_env var=val'")
479 raise UsageError("usage is 'set_env var=val'")
483 var = bits[0].strip()
480 var = bits[0].strip()
484 val = bits[1].strip()
481 val = bits[1].strip()
485 if re.match(r'.*\s.*', var):
482 if re.match(r'.*\s.*', var):
486 # an environment variable with whitespace is almost certainly
483 # an environment variable with whitespace is almost certainly
487 # not what the user intended. what's more likely is the wrong
484 # not what the user intended. what's more likely is the wrong
488 # split was chosen, ie for "set_env cmd_args A=B", we chose
485 # split was chosen, ie for "set_env cmd_args A=B", we chose
489 # '=' for the split and should have chosen ' '. to get around
486 # '=' for the split and should have chosen ' '. to get around
490 # this, users should just assign directly to os.environ or use
487 # this, users should just assign directly to os.environ or use
491 # standard magic {var} expansion.
488 # standard magic {var} expansion.
492 err = "refusing to set env var with whitespace: '{0}'"
489 err = "refusing to set env var with whitespace: '{0}'"
493 err = err.format(val)
490 err = err.format(val)
494 raise UsageError(err)
491 raise UsageError(err)
495 os.environ[var] = val
492 os.environ[var] = val
496 print('env: {0}={1}'.format(var,val))
493 print('env: {0}={1}'.format(var,val))
497
494
498 @line_magic
495 @line_magic
499 def pushd(self, parameter_s=''):
496 def pushd(self, parameter_s=''):
500 """Place the current dir on stack and change directory.
497 """Place the current dir on stack and change directory.
501
498
502 Usage:\\
499 Usage:\\
503 %pushd ['dirname']
500 %pushd ['dirname']
504 """
501 """
505
502
506 dir_s = self.shell.dir_stack
503 dir_s = self.shell.dir_stack
507 tgt = os.path.expanduser(parameter_s)
504 tgt = os.path.expanduser(parameter_s)
508 cwd = os.getcwd().replace(self.shell.home_dir,'~')
505 cwd = os.getcwd().replace(self.shell.home_dir,'~')
509 if tgt:
506 if tgt:
510 self.cd(parameter_s)
507 self.cd(parameter_s)
511 dir_s.insert(0,cwd)
508 dir_s.insert(0,cwd)
512 return self.shell.run_line_magic('dirs', '')
509 return self.shell.run_line_magic('dirs', '')
513
510
514 @line_magic
511 @line_magic
515 def popd(self, parameter_s=''):
512 def popd(self, parameter_s=''):
516 """Change to directory popped off the top of the stack.
513 """Change to directory popped off the top of the stack.
517 """
514 """
518 if not self.shell.dir_stack:
515 if not self.shell.dir_stack:
519 raise UsageError("%popd on empty stack")
516 raise UsageError("%popd on empty stack")
520 top = self.shell.dir_stack.pop(0)
517 top = self.shell.dir_stack.pop(0)
521 self.cd(top)
518 self.cd(top)
522 print("popd ->",top)
519 print("popd ->",top)
523
520
524 @line_magic
521 @line_magic
525 def dirs(self, parameter_s=''):
522 def dirs(self, parameter_s=''):
526 """Return the current directory stack."""
523 """Return the current directory stack."""
527
524
528 return self.shell.dir_stack
525 return self.shell.dir_stack
529
526
530 @line_magic
527 @line_magic
531 def dhist(self, parameter_s=''):
528 def dhist(self, parameter_s=''):
532 """Print your history of visited directories.
529 """Print your history of visited directories.
533
530
534 %dhist -> print full history\\
531 %dhist -> print full history\\
535 %dhist n -> print last n entries only\\
532 %dhist n -> print last n entries only\\
536 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
533 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
537
534
538 This history is automatically maintained by the %cd command, and
535 This history is automatically maintained by the %cd command, and
539 always available as the global list variable _dh. You can use %cd -<n>
536 always available as the global list variable _dh. You can use %cd -<n>
540 to go to directory number <n>.
537 to go to directory number <n>.
541
538
542 Note that most of time, you should view directory history by entering
539 Note that most of time, you should view directory history by entering
543 cd -<TAB>.
540 cd -<TAB>.
544
541
545 """
542 """
546
543
547 dh = self.shell.user_ns['_dh']
544 dh = self.shell.user_ns['_dh']
548 if parameter_s:
545 if parameter_s:
549 try:
546 try:
550 args = map(int,parameter_s.split())
547 args = map(int,parameter_s.split())
551 except:
548 except:
552 self.arg_err(self.dhist)
549 self.arg_err(self.dhist)
553 return
550 return
554 if len(args) == 1:
551 if len(args) == 1:
555 ini,fin = max(len(dh)-(args[0]),0),len(dh)
552 ini,fin = max(len(dh)-(args[0]),0),len(dh)
556 elif len(args) == 2:
553 elif len(args) == 2:
557 ini,fin = args
554 ini,fin = args
558 fin = min(fin, len(dh))
555 fin = min(fin, len(dh))
559 else:
556 else:
560 self.arg_err(self.dhist)
557 self.arg_err(self.dhist)
561 return
558 return
562 else:
559 else:
563 ini,fin = 0,len(dh)
560 ini,fin = 0,len(dh)
564 print('Directory history (kept in _dh)')
561 print('Directory history (kept in _dh)')
565 for i in range(ini, fin):
562 for i in range(ini, fin):
566 print("%d: %s" % (i, dh[i]))
563 print("%d: %s" % (i, dh[i]))
567
564
568 @skip_doctest
565 @skip_doctest
569 @line_magic
566 @line_magic
570 def sc(self, parameter_s=''):
567 def sc(self, parameter_s=''):
571 """Shell capture - run shell command and capture output (DEPRECATED use !).
568 """Shell capture - run shell command and capture output (DEPRECATED use !).
572
569
573 DEPRECATED. Suboptimal, retained for backwards compatibility.
570 DEPRECATED. Suboptimal, retained for backwards compatibility.
574
571
575 You should use the form 'var = !command' instead. Example:
572 You should use the form 'var = !command' instead. Example:
576
573
577 "%sc -l myfiles = ls ~" should now be written as
574 "%sc -l myfiles = ls ~" should now be written as
578
575
579 "myfiles = !ls ~"
576 "myfiles = !ls ~"
580
577
581 myfiles.s, myfiles.l and myfiles.n still apply as documented
578 myfiles.s, myfiles.l and myfiles.n still apply as documented
582 below.
579 below.
583
580
584 --
581 --
585 %sc [options] varname=command
582 %sc [options] varname=command
586
583
587 IPython will run the given command using commands.getoutput(), and
584 IPython will run the given command using commands.getoutput(), and
588 will then update the user's interactive namespace with a variable
585 will then update the user's interactive namespace with a variable
589 called varname, containing the value of the call. Your command can
586 called varname, containing the value of the call. Your command can
590 contain shell wildcards, pipes, etc.
587 contain shell wildcards, pipes, etc.
591
588
592 The '=' sign in the syntax is mandatory, and the variable name you
589 The '=' sign in the syntax is mandatory, and the variable name you
593 supply must follow Python's standard conventions for valid names.
590 supply must follow Python's standard conventions for valid names.
594
591
595 (A special format without variable name exists for internal use)
592 (A special format without variable name exists for internal use)
596
593
597 Options:
594 Options:
598
595
599 -l: list output. Split the output on newlines into a list before
596 -l: list output. Split the output on newlines into a list before
600 assigning it to the given variable. By default the output is stored
597 assigning it to the given variable. By default the output is stored
601 as a single string.
598 as a single string.
602
599
603 -v: verbose. Print the contents of the variable.
600 -v: verbose. Print the contents of the variable.
604
601
605 In most cases you should not need to split as a list, because the
602 In most cases you should not need to split as a list, because the
606 returned value is a special type of string which can automatically
603 returned value is a special type of string which can automatically
607 provide its contents either as a list (split on newlines) or as a
604 provide its contents either as a list (split on newlines) or as a
608 space-separated string. These are convenient, respectively, either
605 space-separated string. These are convenient, respectively, either
609 for sequential processing or to be passed to a shell command.
606 for sequential processing or to be passed to a shell command.
610
607
611 For example::
608 For example::
612
609
613 # Capture into variable a
610 # Capture into variable a
614 In [1]: sc a=ls *py
611 In [1]: sc a=ls *py
615
612
616 # a is a string with embedded newlines
613 # a is a string with embedded newlines
617 In [2]: a
614 In [2]: a
618 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
615 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
619
616
620 # which can be seen as a list:
617 # which can be seen as a list:
621 In [3]: a.l
618 In [3]: a.l
622 Out[3]: ['setup.py', 'win32_manual_post_install.py']
619 Out[3]: ['setup.py', 'win32_manual_post_install.py']
623
620
624 # or as a whitespace-separated string:
621 # or as a whitespace-separated string:
625 In [4]: a.s
622 In [4]: a.s
626 Out[4]: 'setup.py win32_manual_post_install.py'
623 Out[4]: 'setup.py win32_manual_post_install.py'
627
624
628 # a.s is useful to pass as a single command line:
625 # a.s is useful to pass as a single command line:
629 In [5]: !wc -l $a.s
626 In [5]: !wc -l $a.s
630 146 setup.py
627 146 setup.py
631 130 win32_manual_post_install.py
628 130 win32_manual_post_install.py
632 276 total
629 276 total
633
630
634 # while the list form is useful to loop over:
631 # while the list form is useful to loop over:
635 In [6]: for f in a.l:
632 In [6]: for f in a.l:
636 ...: !wc -l $f
633 ...: !wc -l $f
637 ...:
634 ...:
638 146 setup.py
635 146 setup.py
639 130 win32_manual_post_install.py
636 130 win32_manual_post_install.py
640
637
641 Similarly, the lists returned by the -l option are also special, in
638 Similarly, the lists returned by the -l option are also special, in
642 the sense that you can equally invoke the .s attribute on them to
639 the sense that you can equally invoke the .s attribute on them to
643 automatically get a whitespace-separated string from their contents::
640 automatically get a whitespace-separated string from their contents::
644
641
645 In [7]: sc -l b=ls *py
642 In [7]: sc -l b=ls *py
646
643
647 In [8]: b
644 In [8]: b
648 Out[8]: ['setup.py', 'win32_manual_post_install.py']
645 Out[8]: ['setup.py', 'win32_manual_post_install.py']
649
646
650 In [9]: b.s
647 In [9]: b.s
651 Out[9]: 'setup.py win32_manual_post_install.py'
648 Out[9]: 'setup.py win32_manual_post_install.py'
652
649
653 In summary, both the lists and strings used for output capture have
650 In summary, both the lists and strings used for output capture have
654 the following special attributes::
651 the following special attributes::
655
652
656 .l (or .list) : value as list.
653 .l (or .list) : value as list.
657 .n (or .nlstr): value as newline-separated string.
654 .n (or .nlstr): value as newline-separated string.
658 .s (or .spstr): value as space-separated string.
655 .s (or .spstr): value as space-separated string.
659 """
656 """
660
657
661 opts,args = self.parse_options(parameter_s, 'lv')
658 opts,args = self.parse_options(parameter_s, 'lv')
662 # Try to get a variable name and command to run
659 # Try to get a variable name and command to run
663 try:
660 try:
664 # the variable name must be obtained from the parse_options
661 # the variable name must be obtained from the parse_options
665 # output, which uses shlex.split to strip options out.
662 # output, which uses shlex.split to strip options out.
666 var,_ = args.split('=', 1)
663 var,_ = args.split('=', 1)
667 var = var.strip()
664 var = var.strip()
668 # But the command has to be extracted from the original input
665 # But the command has to be extracted from the original input
669 # parameter_s, not on what parse_options returns, to avoid the
666 # parameter_s, not on what parse_options returns, to avoid the
670 # quote stripping which shlex.split performs on it.
667 # quote stripping which shlex.split performs on it.
671 _,cmd = parameter_s.split('=', 1)
668 _,cmd = parameter_s.split('=', 1)
672 except ValueError:
669 except ValueError:
673 var,cmd = '',''
670 var,cmd = '',''
674 # If all looks ok, proceed
671 # If all looks ok, proceed
675 split = 'l' in opts
672 split = 'l' in opts
676 out = self.shell.getoutput(cmd, split=split)
673 out = self.shell.getoutput(cmd, split=split)
677 if 'v' in opts:
674 if 'v' in opts:
678 print('%s ==\n%s' % (var, pformat(out)))
675 print('%s ==\n%s' % (var, pformat(out)))
679 if var:
676 if var:
680 self.shell.user_ns.update({var:out})
677 self.shell.user_ns.update({var:out})
681 else:
678 else:
682 return out
679 return out
683
680
684 @line_cell_magic
681 @line_cell_magic
685 def sx(self, line='', cell=None):
682 def sx(self, line='', cell=None):
686 """Shell execute - run shell command and capture output (!! is short-hand).
683 """Shell execute - run shell command and capture output (!! is short-hand).
687
684
688 %sx command
685 %sx command
689
686
690 IPython will run the given command using commands.getoutput(), and
687 IPython will run the given command using commands.getoutput(), and
691 return the result formatted as a list (split on '\\n'). Since the
688 return the result formatted as a list (split on '\\n'). Since the
692 output is _returned_, it will be stored in ipython's regular output
689 output is _returned_, it will be stored in ipython's regular output
693 cache Out[N] and in the '_N' automatic variables.
690 cache Out[N] and in the '_N' automatic variables.
694
691
695 Notes:
692 Notes:
696
693
697 1) If an input line begins with '!!', then %sx is automatically
694 1) If an input line begins with '!!', then %sx is automatically
698 invoked. That is, while::
695 invoked. That is, while::
699
696
700 !ls
697 !ls
701
698
702 causes ipython to simply issue system('ls'), typing::
699 causes ipython to simply issue system('ls'), typing::
703
700
704 !!ls
701 !!ls
705
702
706 is a shorthand equivalent to::
703 is a shorthand equivalent to::
707
704
708 %sx ls
705 %sx ls
709
706
710 2) %sx differs from %sc in that %sx automatically splits into a list,
707 2) %sx differs from %sc in that %sx automatically splits into a list,
711 like '%sc -l'. The reason for this is to make it as easy as possible
708 like '%sc -l'. The reason for this is to make it as easy as possible
712 to process line-oriented shell output via further python commands.
709 to process line-oriented shell output via further python commands.
713 %sc is meant to provide much finer control, but requires more
710 %sc is meant to provide much finer control, but requires more
714 typing.
711 typing.
715
712
716 3) Just like %sc -l, this is a list with special attributes:
713 3) Just like %sc -l, this is a list with special attributes:
717 ::
714 ::
718
715
719 .l (or .list) : value as list.
716 .l (or .list) : value as list.
720 .n (or .nlstr): value as newline-separated string.
717 .n (or .nlstr): value as newline-separated string.
721 .s (or .spstr): value as whitespace-separated string.
718 .s (or .spstr): value as whitespace-separated string.
722
719
723 This is very useful when trying to use such lists as arguments to
720 This is very useful when trying to use such lists as arguments to
724 system commands."""
721 system commands."""
725
722
726 if cell is None:
723 if cell is None:
727 # line magic
724 # line magic
728 return self.shell.getoutput(line)
725 return self.shell.getoutput(line)
729 else:
726 else:
730 opts,args = self.parse_options(line, '', 'out=')
727 opts,args = self.parse_options(line, '', 'out=')
731 output = self.shell.getoutput(cell)
728 output = self.shell.getoutput(cell)
732 out_name = opts.get('out', opts.get('o'))
729 out_name = opts.get('out', opts.get('o'))
733 if out_name:
730 if out_name:
734 self.shell.user_ns[out_name] = output
731 self.shell.user_ns[out_name] = output
735 else:
732 else:
736 return output
733 return output
737
734
738 system = line_cell_magic('system')(sx)
735 system = line_cell_magic('system')(sx)
739 bang = cell_magic('!')(sx)
736 bang = cell_magic('!')(sx)
740
737
741 @line_magic
738 @line_magic
742 def bookmark(self, parameter_s=''):
739 def bookmark(self, parameter_s=''):
743 """Manage IPython's bookmark system.
740 """Manage IPython's bookmark system.
744
741
745 %bookmark <name> - set bookmark to current dir
742 %bookmark <name> - set bookmark to current dir
746 %bookmark <name> <dir> - set bookmark to <dir>
743 %bookmark <name> <dir> - set bookmark to <dir>
747 %bookmark -l - list all bookmarks
744 %bookmark -l - list all bookmarks
748 %bookmark -d <name> - remove bookmark
745 %bookmark -d <name> - remove bookmark
749 %bookmark -r - remove all bookmarks
746 %bookmark -r - remove all bookmarks
750
747
751 You can later on access a bookmarked folder with::
748 You can later on access a bookmarked folder with::
752
749
753 %cd -b <name>
750 %cd -b <name>
754
751
755 or simply '%cd <name>' if there is no directory called <name> AND
752 or simply '%cd <name>' if there is no directory called <name> AND
756 there is such a bookmark defined.
753 there is such a bookmark defined.
757
754
758 Your bookmarks persist through IPython sessions, but they are
755 Your bookmarks persist through IPython sessions, but they are
759 associated with each profile."""
756 associated with each profile."""
760
757
761 opts,args = self.parse_options(parameter_s,'drl',mode='list')
758 opts,args = self.parse_options(parameter_s,'drl',mode='list')
762 if len(args) > 2:
759 if len(args) > 2:
763 raise UsageError("%bookmark: too many arguments")
760 raise UsageError("%bookmark: too many arguments")
764
761
765 bkms = self.shell.db.get('bookmarks',{})
762 bkms = self.shell.db.get('bookmarks',{})
766
763
767 if 'd' in opts:
764 if 'd' in opts:
768 try:
765 try:
769 todel = args[0]
766 todel = args[0]
770 except IndexError as e:
767 except IndexError as e:
771 raise UsageError(
768 raise UsageError(
772 "%bookmark -d: must provide a bookmark to delete") from e
769 "%bookmark -d: must provide a bookmark to delete") from e
773 else:
770 else:
774 try:
771 try:
775 del bkms[todel]
772 del bkms[todel]
776 except KeyError as e:
773 except KeyError as e:
777 raise UsageError(
774 raise UsageError(
778 "%%bookmark -d: Can't delete bookmark '%s'" % todel) from e
775 "%%bookmark -d: Can't delete bookmark '%s'" % todel) from e
779
776
780 elif 'r' in opts:
777 elif 'r' in opts:
781 bkms = {}
778 bkms = {}
782 elif 'l' in opts:
779 elif 'l' in opts:
783 bks = sorted(bkms)
780 bks = sorted(bkms)
784 if bks:
781 if bks:
785 size = max(map(len, bks))
782 size = max(map(len, bks))
786 else:
783 else:
787 size = 0
784 size = 0
788 fmt = '%-'+str(size)+'s -> %s'
785 fmt = '%-'+str(size)+'s -> %s'
789 print('Current bookmarks:')
786 print('Current bookmarks:')
790 for bk in bks:
787 for bk in bks:
791 print(fmt % (bk, bkms[bk]))
788 print(fmt % (bk, bkms[bk]))
792 else:
789 else:
793 if not args:
790 if not args:
794 raise UsageError("%bookmark: You must specify the bookmark name")
791 raise UsageError("%bookmark: You must specify the bookmark name")
795 elif len(args)==1:
792 elif len(args)==1:
796 bkms[args[0]] = os.getcwd()
793 bkms[args[0]] = os.getcwd()
797 elif len(args)==2:
794 elif len(args)==2:
798 bkms[args[0]] = args[1]
795 bkms[args[0]] = args[1]
799 self.shell.db['bookmarks'] = bkms
796 self.shell.db['bookmarks'] = bkms
800
797
801 @line_magic
798 @line_magic
802 def pycat(self, parameter_s=''):
799 def pycat(self, parameter_s=''):
803 """Show a syntax-highlighted file through a pager.
800 """Show a syntax-highlighted file through a pager.
804
801
805 This magic is similar to the cat utility, but it will assume the file
802 This magic is similar to the cat utility, but it will assume the file
806 to be Python source and will show it with syntax highlighting.
803 to be Python source and will show it with syntax highlighting.
807
804
808 This magic command can either take a local filename, an url,
805 This magic command can either take a local filename, an url,
809 an history range (see %history) or a macro as argument.
806 an history range (see %history) or a macro as argument.
810
807
811 If no parameter is given, prints out history of current session up to
808 If no parameter is given, prints out history of current session up to
812 this point. ::
809 this point. ::
813
810
814 %pycat myscript.py
811 %pycat myscript.py
815 %pycat 7-27
812 %pycat 7-27
816 %pycat myMacro
813 %pycat myMacro
817 %pycat http://www.example.com/myscript.py
814 %pycat http://www.example.com/myscript.py
818 """
815 """
819 try:
816 try:
820 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
817 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
821 except (ValueError, IOError):
818 except (ValueError, IOError):
822 print("Error: no such file, variable, URL, history range or macro")
819 print("Error: no such file, variable, URL, history range or macro")
823 return
820 return
824
821
825 page.page(self.shell.pycolorize(source_to_unicode(cont)))
822 page.page(self.shell.pycolorize(source_to_unicode(cont)))
826
823
827 @magic_arguments.magic_arguments()
824 @magic_arguments.magic_arguments()
828 @magic_arguments.argument(
825 @magic_arguments.argument(
829 '-a', '--append', action='store_true', default=False,
826 '-a', '--append', action='store_true', default=False,
830 help='Append contents of the cell to an existing file. '
827 help='Append contents of the cell to an existing file. '
831 'The file will be created if it does not exist.'
828 'The file will be created if it does not exist.'
832 )
829 )
833 @magic_arguments.argument(
830 @magic_arguments.argument(
834 'filename', type=str,
831 'filename', type=str,
835 help='file to write'
832 help='file to write'
836 )
833 )
837 @cell_magic
834 @cell_magic
838 def writefile(self, line, cell):
835 def writefile(self, line, cell):
839 """Write the contents of the cell to a file.
836 """Write the contents of the cell to a file.
840
837
841 The file will be overwritten unless the -a (--append) flag is specified.
838 The file will be overwritten unless the -a (--append) flag is specified.
842 """
839 """
843 args = magic_arguments.parse_argstring(self.writefile, line)
840 args = magic_arguments.parse_argstring(self.writefile, line)
844 if re.match(r'^(\'.*\')|(".*")$', args.filename):
841 if re.match(r'^(\'.*\')|(".*")$', args.filename):
845 filename = os.path.expanduser(args.filename[1:-1])
842 filename = os.path.expanduser(args.filename[1:-1])
846 else:
843 else:
847 filename = os.path.expanduser(args.filename)
844 filename = os.path.expanduser(args.filename)
848
845
849 if os.path.exists(filename):
846 if os.path.exists(filename):
850 if args.append:
847 if args.append:
851 print("Appending to %s" % filename)
848 print("Appending to %s" % filename)
852 else:
849 else:
853 print("Overwriting %s" % filename)
850 print("Overwriting %s" % filename)
854 else:
851 else:
855 print("Writing %s" % filename)
852 print("Writing %s" % filename)
856
853
857 mode = 'a' if args.append else 'w'
854 mode = 'a' if args.append else 'w'
858 with io.open(filename, mode, encoding='utf-8') as f:
855 with io.open(filename, mode, encoding='utf-8') as f:
859 f.write(cell)
856 f.write(cell)
General Comments 0
You need to be logged in to leave comments. Login now