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