##// END OF EJS Templates
Don't use nbformat.current in core
MinRK -
Show More

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

1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,609 +1,611 b''
1 1 """Implementation of basic magic functions."""
2 2
3 3 from __future__ import print_function
4 4
5 5 import io
6 6 import json
7 7 import sys
8 8 from pprint import pformat
9 9
10 10 from IPython.core import magic_arguments, page
11 11 from IPython.core.error import UsageError
12 12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
13 13 from IPython.utils.text import format_screen, dedent, indent
14 14 from IPython.testing.skipdoctest import skip_doctest
15 15 from IPython.utils.ipstruct import Struct
16 16 from IPython.utils.path import unquote_filename
17 17 from IPython.utils.py3compat import unicode_type
18 18 from IPython.utils.warn import warn, error
19 19
20 20
21 21 class MagicsDisplay(object):
22 22 def __init__(self, magics_manager):
23 23 self.magics_manager = magics_manager
24 24
25 25 def _lsmagic(self):
26 26 """The main implementation of the %lsmagic"""
27 27 mesc = magic_escapes['line']
28 28 cesc = magic_escapes['cell']
29 29 mman = self.magics_manager
30 30 magics = mman.lsmagic()
31 31 out = ['Available line magics:',
32 32 mesc + (' '+mesc).join(sorted(magics['line'])),
33 33 '',
34 34 'Available cell magics:',
35 35 cesc + (' '+cesc).join(sorted(magics['cell'])),
36 36 '',
37 37 mman.auto_status()]
38 38 return '\n'.join(out)
39 39
40 40 def _repr_pretty_(self, p, cycle):
41 41 p.text(self._lsmagic())
42 42
43 43 def __str__(self):
44 44 return self._lsmagic()
45 45
46 46 def _jsonable(self):
47 47 """turn magics dict into jsonable dict of the same structure
48 48
49 49 replaces object instances with their class names as strings
50 50 """
51 51 magic_dict = {}
52 52 mman = self.magics_manager
53 53 magics = mman.lsmagic()
54 54 for key, subdict in magics.items():
55 55 d = {}
56 56 magic_dict[key] = d
57 57 for name, obj in subdict.items():
58 58 try:
59 59 classname = obj.__self__.__class__.__name__
60 60 except AttributeError:
61 61 classname = 'Other'
62 62
63 63 d[name] = classname
64 64 return magic_dict
65 65
66 66 def _repr_json_(self):
67 67 return json.dumps(self._jsonable())
68 68
69 69
70 70 @magics_class
71 71 class BasicMagics(Magics):
72 72 """Magics that provide central IPython functionality.
73 73
74 74 These are various magics that don't fit into specific categories but that
75 75 are all part of the base 'IPython experience'."""
76 76
77 77 @magic_arguments.magic_arguments()
78 78 @magic_arguments.argument(
79 79 '-l', '--line', action='store_true',
80 80 help="""Create a line magic alias."""
81 81 )
82 82 @magic_arguments.argument(
83 83 '-c', '--cell', action='store_true',
84 84 help="""Create a cell magic alias."""
85 85 )
86 86 @magic_arguments.argument(
87 87 'name',
88 88 help="""Name of the magic to be created."""
89 89 )
90 90 @magic_arguments.argument(
91 91 'target',
92 92 help="""Name of the existing line or cell magic."""
93 93 )
94 94 @line_magic
95 95 def alias_magic(self, line=''):
96 96 """Create an alias for an existing line or cell magic.
97 97
98 98 Examples
99 99 --------
100 100 ::
101 101
102 102 In [1]: %alias_magic t timeit
103 103 Created `%t` as an alias for `%timeit`.
104 104 Created `%%t` as an alias for `%%timeit`.
105 105
106 106 In [2]: %t -n1 pass
107 107 1 loops, best of 3: 954 ns per loop
108 108
109 109 In [3]: %%t -n1
110 110 ...: pass
111 111 ...:
112 112 1 loops, best of 3: 954 ns per loop
113 113
114 114 In [4]: %alias_magic --cell whereami pwd
115 115 UsageError: Cell magic function `%%pwd` not found.
116 116 In [5]: %alias_magic --line whereami pwd
117 117 Created `%whereami` as an alias for `%pwd`.
118 118
119 119 In [6]: %whereami
120 120 Out[6]: u'/home/testuser'
121 121 """
122 122 args = magic_arguments.parse_argstring(self.alias_magic, line)
123 123 shell = self.shell
124 124 mman = self.shell.magics_manager
125 125 escs = ''.join(magic_escapes.values())
126 126
127 127 target = args.target.lstrip(escs)
128 128 name = args.name.lstrip(escs)
129 129
130 130 # Find the requested magics.
131 131 m_line = shell.find_magic(target, 'line')
132 132 m_cell = shell.find_magic(target, 'cell')
133 133 if args.line and m_line is None:
134 134 raise UsageError('Line magic function `%s%s` not found.' %
135 135 (magic_escapes['line'], target))
136 136 if args.cell and m_cell is None:
137 137 raise UsageError('Cell magic function `%s%s` not found.' %
138 138 (magic_escapes['cell'], target))
139 139
140 140 # If --line and --cell are not specified, default to the ones
141 141 # that are available.
142 142 if not args.line and not args.cell:
143 143 if not m_line and not m_cell:
144 144 raise UsageError(
145 145 'No line or cell magic with name `%s` found.' % target
146 146 )
147 147 args.line = bool(m_line)
148 148 args.cell = bool(m_cell)
149 149
150 150 if args.line:
151 151 mman.register_alias(name, target, 'line')
152 152 print('Created `%s%s` as an alias for `%s%s`.' % (
153 153 magic_escapes['line'], name,
154 154 magic_escapes['line'], target))
155 155
156 156 if args.cell:
157 157 mman.register_alias(name, target, 'cell')
158 158 print('Created `%s%s` as an alias for `%s%s`.' % (
159 159 magic_escapes['cell'], name,
160 160 magic_escapes['cell'], target))
161 161
162 162 @line_magic
163 163 def lsmagic(self, parameter_s=''):
164 164 """List currently available magic functions."""
165 165 return MagicsDisplay(self.shell.magics_manager)
166 166
167 167 def _magic_docs(self, brief=False, rest=False):
168 168 """Return docstrings from magic functions."""
169 169 mman = self.shell.magics_manager
170 170 docs = mman.lsmagic_docs(brief, missing='No documentation')
171 171
172 172 if rest:
173 173 format_string = '**%s%s**::\n\n%s\n\n'
174 174 else:
175 175 format_string = '%s%s:\n%s\n'
176 176
177 177 return ''.join(
178 178 [format_string % (magic_escapes['line'], fname,
179 179 indent(dedent(fndoc)))
180 180 for fname, fndoc in sorted(docs['line'].items())]
181 181 +
182 182 [format_string % (magic_escapes['cell'], fname,
183 183 indent(dedent(fndoc)))
184 184 for fname, fndoc in sorted(docs['cell'].items())]
185 185 )
186 186
187 187 @line_magic
188 188 def magic(self, parameter_s=''):
189 189 """Print information about the magic function system.
190 190
191 191 Supported formats: -latex, -brief, -rest
192 192 """
193 193
194 194 mode = ''
195 195 try:
196 196 mode = parameter_s.split()[0][1:]
197 197 if mode == 'rest':
198 198 rest_docs = []
199 199 except IndexError:
200 200 pass
201 201
202 202 brief = (mode == 'brief')
203 203 rest = (mode == 'rest')
204 204 magic_docs = self._magic_docs(brief, rest)
205 205
206 206 if mode == 'latex':
207 207 print(self.format_latex(magic_docs))
208 208 return
209 209 else:
210 210 magic_docs = format_screen(magic_docs)
211 211
212 212 out = ["""
213 213 IPython's 'magic' functions
214 214 ===========================
215 215
216 216 The magic function system provides a series of functions which allow you to
217 217 control the behavior of IPython itself, plus a lot of system-type
218 218 features. There are two kinds of magics, line-oriented and cell-oriented.
219 219
220 220 Line magics are prefixed with the % character and work much like OS
221 221 command-line calls: they get as an argument the rest of the line, where
222 222 arguments are passed without parentheses or quotes. For example, this will
223 223 time the given statement::
224 224
225 225 %timeit range(1000)
226 226
227 227 Cell magics are prefixed with a double %%, and they are functions that get as
228 228 an argument not only the rest of the line, but also the lines below it in a
229 229 separate argument. These magics are called with two arguments: the rest of the
230 230 call line and the body of the cell, consisting of the lines below the first.
231 231 For example::
232 232
233 233 %%timeit x = numpy.random.randn((100, 100))
234 234 numpy.linalg.svd(x)
235 235
236 236 will time the execution of the numpy svd routine, running the assignment of x
237 237 as part of the setup phase, which is not timed.
238 238
239 239 In a line-oriented client (the terminal or Qt console IPython), starting a new
240 240 input with %% will automatically enter cell mode, and IPython will continue
241 241 reading input until a blank line is given. In the notebook, simply type the
242 242 whole cell as one entity, but keep in mind that the %% escape can only be at
243 243 the very start of the cell.
244 244
245 245 NOTE: If you have 'automagic' enabled (via the command line option or with the
246 246 %automagic function), you don't need to type in the % explicitly for line
247 247 magics; cell magics always require an explicit '%%' escape. By default,
248 248 IPython ships with automagic on, so you should only rarely need the % escape.
249 249
250 250 Example: typing '%cd mydir' (without the quotes) changes you working directory
251 251 to 'mydir', if it exists.
252 252
253 253 For a list of the available magic functions, use %lsmagic. For a description
254 254 of any of them, type %magic_name?, e.g. '%cd?'.
255 255
256 256 Currently the magic system has the following functions:""",
257 257 magic_docs,
258 258 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
259 259 str(self.lsmagic()),
260 260 ]
261 261 page.page('\n'.join(out))
262 262
263 263
264 264 @line_magic
265 265 def page(self, parameter_s=''):
266 266 """Pretty print the object and display it through a pager.
267 267
268 268 %page [options] OBJECT
269 269
270 270 If no object is given, use _ (last output).
271 271
272 272 Options:
273 273
274 274 -r: page str(object), don't pretty-print it."""
275 275
276 276 # After a function contributed by Olivier Aubert, slightly modified.
277 277
278 278 # Process options/args
279 279 opts, args = self.parse_options(parameter_s, 'r')
280 280 raw = 'r' in opts
281 281
282 282 oname = args and args or '_'
283 283 info = self.shell._ofind(oname)
284 284 if info['found']:
285 285 txt = (raw and str or pformat)( info['obj'] )
286 286 page.page(txt)
287 287 else:
288 288 print('Object `%s` not found' % oname)
289 289
290 290 @line_magic
291 291 def profile(self, parameter_s=''):
292 292 """Print your currently active IPython profile.
293 293
294 294 See Also
295 295 --------
296 296 prun : run code using the Python profiler
297 297 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
298 298 """
299 299 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
300 300 from IPython.core.application import BaseIPythonApplication
301 301 if BaseIPythonApplication.initialized():
302 302 print(BaseIPythonApplication.instance().profile)
303 303 else:
304 304 error("profile is an application-level value, but you don't appear to be in an IPython application")
305 305
306 306 @line_magic
307 307 def pprint(self, parameter_s=''):
308 308 """Toggle pretty printing on/off."""
309 309 ptformatter = self.shell.display_formatter.formatters['text/plain']
310 310 ptformatter.pprint = bool(1 - ptformatter.pprint)
311 311 print('Pretty printing has been turned',
312 312 ['OFF','ON'][ptformatter.pprint])
313 313
314 314 @line_magic
315 315 def colors(self, parameter_s=''):
316 316 """Switch color scheme for prompts, info system and exception handlers.
317 317
318 318 Currently implemented schemes: NoColor, Linux, LightBG.
319 319
320 320 Color scheme names are not case-sensitive.
321 321
322 322 Examples
323 323 --------
324 324 To get a plain black and white terminal::
325 325
326 326 %colors nocolor
327 327 """
328 328 def color_switch_err(name):
329 329 warn('Error changing %s color schemes.\n%s' %
330 330 (name, sys.exc_info()[1]))
331 331
332 332
333 333 new_scheme = parameter_s.strip()
334 334 if not new_scheme:
335 335 raise UsageError(
336 336 "%colors: you must specify a color scheme. See '%colors?'")
337 337 # local shortcut
338 338 shell = self.shell
339 339
340 340 import IPython.utils.rlineimpl as readline
341 341
342 342 if not shell.colors_force and \
343 343 not readline.have_readline and \
344 344 (sys.platform == "win32" or sys.platform == "cli"):
345 345 msg = """\
346 346 Proper color support under MS Windows requires the pyreadline library.
347 347 You can find it at:
348 348 http://ipython.org/pyreadline.html
349 349
350 350 Defaulting color scheme to 'NoColor'"""
351 351 new_scheme = 'NoColor'
352 352 warn(msg)
353 353
354 354 # readline option is 0
355 355 if not shell.colors_force and not shell.has_readline:
356 356 new_scheme = 'NoColor'
357 357
358 358 # Set prompt colors
359 359 try:
360 360 shell.prompt_manager.color_scheme = new_scheme
361 361 except:
362 362 color_switch_err('prompt')
363 363 else:
364 364 shell.colors = \
365 365 shell.prompt_manager.color_scheme_table.active_scheme_name
366 366 # Set exception colors
367 367 try:
368 368 shell.InteractiveTB.set_colors(scheme = new_scheme)
369 369 shell.SyntaxTB.set_colors(scheme = new_scheme)
370 370 except:
371 371 color_switch_err('exception')
372 372
373 373 # Set info (for 'object?') colors
374 374 if shell.color_info:
375 375 try:
376 376 shell.inspector.set_active_scheme(new_scheme)
377 377 except:
378 378 color_switch_err('object inspector')
379 379 else:
380 380 shell.inspector.set_active_scheme('NoColor')
381 381
382 382 @line_magic
383 383 def xmode(self, parameter_s=''):
384 384 """Switch modes for the exception handlers.
385 385
386 386 Valid modes: Plain, Context and Verbose.
387 387
388 388 If called without arguments, acts as a toggle."""
389 389
390 390 def xmode_switch_err(name):
391 391 warn('Error changing %s exception modes.\n%s' %
392 392 (name,sys.exc_info()[1]))
393 393
394 394 shell = self.shell
395 395 new_mode = parameter_s.strip().capitalize()
396 396 try:
397 397 shell.InteractiveTB.set_mode(mode=new_mode)
398 398 print('Exception reporting mode:',shell.InteractiveTB.mode)
399 399 except:
400 400 xmode_switch_err('user')
401 401
402 402 @line_magic
403 403 def quickref(self,arg):
404 404 """ Show a quick reference sheet """
405 405 from IPython.core.usage import quick_reference
406 406 qr = quick_reference + self._magic_docs(brief=True)
407 407 page.page(qr)
408 408
409 409 @line_magic
410 410 def doctest_mode(self, parameter_s=''):
411 411 """Toggle doctest mode on and off.
412 412
413 413 This mode is intended to make IPython behave as much as possible like a
414 414 plain Python shell, from the perspective of how its prompts, exceptions
415 415 and output look. This makes it easy to copy and paste parts of a
416 416 session into doctests. It does so by:
417 417
418 418 - Changing the prompts to the classic ``>>>`` ones.
419 419 - Changing the exception reporting mode to 'Plain'.
420 420 - Disabling pretty-printing of output.
421 421
422 422 Note that IPython also supports the pasting of code snippets that have
423 423 leading '>>>' and '...' prompts in them. This means that you can paste
424 424 doctests from files or docstrings (even if they have leading
425 425 whitespace), and the code will execute correctly. You can then use
426 426 '%history -t' to see the translated history; this will give you the
427 427 input after removal of all the leading prompts and whitespace, which
428 428 can be pasted back into an editor.
429 429
430 430 With these features, you can switch into this mode easily whenever you
431 431 need to do testing and changes to doctests, without having to leave
432 432 your existing IPython session.
433 433 """
434 434
435 435 # Shorthands
436 436 shell = self.shell
437 437 pm = shell.prompt_manager
438 438 meta = shell.meta
439 439 disp_formatter = self.shell.display_formatter
440 440 ptformatter = disp_formatter.formatters['text/plain']
441 441 # dstore is a data store kept in the instance metadata bag to track any
442 442 # changes we make, so we can undo them later.
443 443 dstore = meta.setdefault('doctest_mode',Struct())
444 444 save_dstore = dstore.setdefault
445 445
446 446 # save a few values we'll need to recover later
447 447 mode = save_dstore('mode',False)
448 448 save_dstore('rc_pprint',ptformatter.pprint)
449 449 save_dstore('xmode',shell.InteractiveTB.mode)
450 450 save_dstore('rc_separate_out',shell.separate_out)
451 451 save_dstore('rc_separate_out2',shell.separate_out2)
452 452 save_dstore('rc_prompts_pad_left',pm.justify)
453 453 save_dstore('rc_separate_in',shell.separate_in)
454 454 save_dstore('rc_active_types',disp_formatter.active_types)
455 455 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
456 456
457 457 if mode == False:
458 458 # turn on
459 459 pm.in_template = '>>> '
460 460 pm.in2_template = '... '
461 461 pm.out_template = ''
462 462
463 463 # Prompt separators like plain python
464 464 shell.separate_in = ''
465 465 shell.separate_out = ''
466 466 shell.separate_out2 = ''
467 467
468 468 pm.justify = False
469 469
470 470 ptformatter.pprint = False
471 471 disp_formatter.active_types = ['text/plain']
472 472
473 473 shell.magic('xmode Plain')
474 474 else:
475 475 # turn off
476 476 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
477 477
478 478 shell.separate_in = dstore.rc_separate_in
479 479
480 480 shell.separate_out = dstore.rc_separate_out
481 481 shell.separate_out2 = dstore.rc_separate_out2
482 482
483 483 pm.justify = dstore.rc_prompts_pad_left
484 484
485 485 ptformatter.pprint = dstore.rc_pprint
486 486 disp_formatter.active_types = dstore.rc_active_types
487 487
488 488 shell.magic('xmode ' + dstore.xmode)
489 489
490 490 # Store new mode and inform
491 491 dstore.mode = bool(1-int(mode))
492 492 mode_label = ['OFF','ON'][dstore.mode]
493 493 print('Doctest mode is:', mode_label)
494 494
495 495 @line_magic
496 496 def gui(self, parameter_s=''):
497 497 """Enable or disable IPython GUI event loop integration.
498 498
499 499 %gui [GUINAME]
500 500
501 501 This magic replaces IPython's threaded shells that were activated
502 502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
503 503 can now be enabled at runtime and keyboard
504 504 interrupts should work without any problems. The following toolkits
505 505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
506 506
507 507 %gui wx # enable wxPython event loop integration
508 508 %gui qt4|qt # enable PyQt4 event loop integration
509 509 %gui qt5 # enable PyQt5 event loop integration
510 510 %gui gtk # enable PyGTK event loop integration
511 511 %gui gtk3 # enable Gtk3 event loop integration
512 512 %gui tk # enable Tk event loop integration
513 513 %gui osx # enable Cocoa event loop integration
514 514 # (requires %matplotlib 1.1)
515 515 %gui # disable all event loop integration
516 516
517 517 WARNING: after any of these has been called you can simply create
518 518 an application object, but DO NOT start the event loop yourself, as
519 519 we have already handled that.
520 520 """
521 521 opts, arg = self.parse_options(parameter_s, '')
522 522 if arg=='': arg = None
523 523 try:
524 524 return self.shell.enable_gui(arg)
525 525 except Exception as e:
526 526 # print simple error message, rather than traceback if we can't
527 527 # hook up the GUI
528 528 error(str(e))
529 529
530 530 @skip_doctest
531 531 @line_magic
532 532 def precision(self, s=''):
533 533 """Set floating point precision for pretty printing.
534 534
535 535 Can set either integer precision or a format string.
536 536
537 537 If numpy has been imported and precision is an int,
538 538 numpy display precision will also be set, via ``numpy.set_printoptions``.
539 539
540 540 If no argument is given, defaults will be restored.
541 541
542 542 Examples
543 543 --------
544 544 ::
545 545
546 546 In [1]: from math import pi
547 547
548 548 In [2]: %precision 3
549 549 Out[2]: u'%.3f'
550 550
551 551 In [3]: pi
552 552 Out[3]: 3.142
553 553
554 554 In [4]: %precision %i
555 555 Out[4]: u'%i'
556 556
557 557 In [5]: pi
558 558 Out[5]: 3
559 559
560 560 In [6]: %precision %e
561 561 Out[6]: u'%e'
562 562
563 563 In [7]: pi**10
564 564 Out[7]: 9.364805e+04
565 565
566 566 In [8]: %precision
567 567 Out[8]: u'%r'
568 568
569 569 In [9]: pi**10
570 570 Out[9]: 93648.047476082982
571 571 """
572 572 ptformatter = self.shell.display_formatter.formatters['text/plain']
573 573 ptformatter.float_precision = s
574 574 return ptformatter.float_format
575 575
576 576 @magic_arguments.magic_arguments()
577 577 @magic_arguments.argument(
578 578 '-e', '--export', action='store_true', default=False,
579 579 help='Export IPython history as a notebook. The filename argument '
580 580 'is used to specify the notebook name and format. For example '
581 581 'a filename of notebook.ipynb will result in a notebook name '
582 582 'of "notebook" and a format of "json". Likewise using a ".py" '
583 583 'file extension will write the notebook as a Python script'
584 584 )
585 585 @magic_arguments.argument(
586 586 'filename', type=unicode_type,
587 587 help='Notebook name or filename'
588 588 )
589 589 @line_magic
590 590 def notebook(self, s):
591 591 """Export and convert IPython notebooks.
592 592
593 593 This function can export the current IPython history to a notebook file.
594 594 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
595 595 To export the history to "foo.py" do "%notebook -e foo.py".
596 596 """
597 597 args = magic_arguments.parse_argstring(self.notebook, s)
598 598
599 from IPython.nbformat import current
599 from IPython.nbformat import write, v4
600 600 args.filename = unquote_filename(args.filename)
601 601 if args.export:
602 602 cells = []
603 603 hist = list(self.shell.history_manager.get_range())
604 for session, prompt_number, input in hist[:-1]:
605 cells.append(current.new_code_cell(prompt_number=prompt_number,
606 input=input))
607 nb = current.new_notebook(cells=cells)
604 for session, execution_count, input in hist[:-1]:
605 cells.append(v4.new_code_cell(
606 execution_count=execution_count,
607 source=source
608 ))
609 nb = v4.new_notebook(cells=cells)
608 610 with io.open(args.filename, 'w', encoding='utf-8') as f:
609 current.write(nb, f)
611 write(f, nb, version=4)
@@ -1,962 +1,955 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 from __future__ import absolute_import
7 7
8 #-----------------------------------------------------------------------------
9 # Imports
10 #-----------------------------------------------------------------------------
11
12 8 import io
13 9 import os
14 10 import sys
15 11 from unittest import TestCase, skipIf
16 12
17 13 try:
18 14 from importlib import invalidate_caches # Required from Python 3.3
19 15 except ImportError:
20 16 def invalidate_caches():
21 17 pass
22 18
23 19 import nose.tools as nt
24 20
25 21 from IPython.core import magic
26 22 from IPython.core.magic import (Magics, magics_class, line_magic,
27 23 cell_magic, line_cell_magic,
28 24 register_line_magic, register_cell_magic,
29 25 register_line_cell_magic)
30 26 from IPython.core.magics import execution, script, code
31 27 from IPython.testing import decorators as dec
32 28 from IPython.testing import tools as tt
33 29 from IPython.utils import py3compat
34 30 from IPython.utils.io import capture_output
35 31 from IPython.utils.tempdir import TemporaryDirectory
36 32 from IPython.utils.process import find_cmd
37 33
38 34 if py3compat.PY3:
39 35 from io import StringIO
40 36 else:
41 37 from StringIO import StringIO
42 38
43 #-----------------------------------------------------------------------------
44 # Test functions begin
45 #-----------------------------------------------------------------------------
46 39
47 40 @magic.magics_class
48 41 class DummyMagics(magic.Magics): pass
49 42
50 43 def test_extract_code_ranges():
51 44 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
52 45 expected = [(0, 1),
53 46 (2, 3),
54 47 (4, 6),
55 48 (6, 9),
56 49 (9, 14),
57 50 (16, None),
58 51 (None, 9),
59 52 (9, None),
60 53 (None, 13),
61 54 (None, None)]
62 55 actual = list(code.extract_code_ranges(instr))
63 56 nt.assert_equal(actual, expected)
64 57
65 58 def test_extract_symbols():
66 59 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
67 60 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
68 61 expected = [([], ['a']),
69 62 (["def b():\n return 42\n"], []),
70 63 (["class A: pass\n"], []),
71 64 (["class A: pass\n", "def b():\n return 42\n"], []),
72 65 (["class A: pass\n"], ['a']),
73 66 ([], ['z'])]
74 67 for symbols, exp in zip(symbols_args, expected):
75 68 nt.assert_equal(code.extract_symbols(source, symbols), exp)
76 69
77 70
78 71 def test_extract_symbols_raises_exception_with_non_python_code():
79 72 source = ("=begin A Ruby program :)=end\n"
80 73 "def hello\n"
81 74 "puts 'Hello world'\n"
82 75 "end")
83 76 with nt.assert_raises(SyntaxError):
84 77 code.extract_symbols(source, "hello")
85 78
86 79 def test_config():
87 80 """ test that config magic does not raise
88 81 can happen if Configurable init is moved too early into
89 82 Magics.__init__ as then a Config object will be registerd as a
90 83 magic.
91 84 """
92 85 ## should not raise.
93 86 _ip.magic('config')
94 87
95 88 def test_rehashx():
96 89 # clear up everything
97 90 _ip = get_ipython()
98 91 _ip.alias_manager.clear_aliases()
99 92 del _ip.db['syscmdlist']
100 93
101 94 _ip.magic('rehashx')
102 95 # Practically ALL ipython development systems will have more than 10 aliases
103 96
104 97 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
105 98 for name, cmd in _ip.alias_manager.aliases:
106 99 # we must strip dots from alias names
107 100 nt.assert_not_in('.', name)
108 101
109 102 # rehashx must fill up syscmdlist
110 103 scoms = _ip.db['syscmdlist']
111 104 nt.assert_true(len(scoms) > 10)
112 105
113 106
114 107 def test_magic_parse_options():
115 108 """Test that we don't mangle paths when parsing magic options."""
116 109 ip = get_ipython()
117 110 path = 'c:\\x'
118 111 m = DummyMagics(ip)
119 112 opts = m.parse_options('-f %s' % path,'f:')[0]
120 113 # argv splitting is os-dependent
121 114 if os.name == 'posix':
122 115 expected = 'c:x'
123 116 else:
124 117 expected = path
125 118 nt.assert_equal(opts['f'], expected)
126 119
127 120 def test_magic_parse_long_options():
128 121 """Magic.parse_options can handle --foo=bar long options"""
129 122 ip = get_ipython()
130 123 m = DummyMagics(ip)
131 124 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
132 125 nt.assert_in('foo', opts)
133 126 nt.assert_in('bar', opts)
134 127 nt.assert_equal(opts['bar'], "bubble")
135 128
136 129
137 130 @dec.skip_without('sqlite3')
138 131 def doctest_hist_f():
139 132 """Test %hist -f with temporary filename.
140 133
141 134 In [9]: import tempfile
142 135
143 136 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
144 137
145 138 In [11]: %hist -nl -f $tfile 3
146 139
147 140 In [13]: import os; os.unlink(tfile)
148 141 """
149 142
150 143
151 144 @dec.skip_without('sqlite3')
152 145 def doctest_hist_r():
153 146 """Test %hist -r
154 147
155 148 XXX - This test is not recording the output correctly. For some reason, in
156 149 testing mode the raw history isn't getting populated. No idea why.
157 150 Disabling the output checking for now, though at least we do run it.
158 151
159 152 In [1]: 'hist' in _ip.lsmagic()
160 153 Out[1]: True
161 154
162 155 In [2]: x=1
163 156
164 157 In [3]: %hist -rl 2
165 158 x=1 # random
166 159 %hist -r 2
167 160 """
168 161
169 162
170 163 @dec.skip_without('sqlite3')
171 164 def doctest_hist_op():
172 165 """Test %hist -op
173 166
174 167 In [1]: class b(float):
175 168 ...: pass
176 169 ...:
177 170
178 171 In [2]: class s(object):
179 172 ...: def __str__(self):
180 173 ...: return 's'
181 174 ...:
182 175
183 176 In [3]:
184 177
185 178 In [4]: class r(b):
186 179 ...: def __repr__(self):
187 180 ...: return 'r'
188 181 ...:
189 182
190 183 In [5]: class sr(s,r): pass
191 184 ...:
192 185
193 186 In [6]:
194 187
195 188 In [7]: bb=b()
196 189
197 190 In [8]: ss=s()
198 191
199 192 In [9]: rr=r()
200 193
201 194 In [10]: ssrr=sr()
202 195
203 196 In [11]: 4.5
204 197 Out[11]: 4.5
205 198
206 199 In [12]: str(ss)
207 200 Out[12]: 's'
208 201
209 202 In [13]:
210 203
211 204 In [14]: %hist -op
212 205 >>> class b:
213 206 ... pass
214 207 ...
215 208 >>> class s(b):
216 209 ... def __str__(self):
217 210 ... return 's'
218 211 ...
219 212 >>>
220 213 >>> class r(b):
221 214 ... def __repr__(self):
222 215 ... return 'r'
223 216 ...
224 217 >>> class sr(s,r): pass
225 218 >>>
226 219 >>> bb=b()
227 220 >>> ss=s()
228 221 >>> rr=r()
229 222 >>> ssrr=sr()
230 223 >>> 4.5
231 224 4.5
232 225 >>> str(ss)
233 226 's'
234 227 >>>
235 228 """
236 229
237 230 def test_hist_pof():
238 231 ip = get_ipython()
239 232 ip.run_cell(u"1+2", store_history=True)
240 233 #raise Exception(ip.history_manager.session_number)
241 234 #raise Exception(list(ip.history_manager._get_range_session()))
242 235 with TemporaryDirectory() as td:
243 236 tf = os.path.join(td, 'hist.py')
244 237 ip.run_line_magic('history', '-pof %s' % tf)
245 238 assert os.path.isfile(tf)
246 239
247 240
248 241 @dec.skip_without('sqlite3')
249 242 def test_macro():
250 243 ip = get_ipython()
251 244 ip.history_manager.reset() # Clear any existing history.
252 245 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
253 246 for i, cmd in enumerate(cmds, start=1):
254 247 ip.history_manager.store_inputs(i, cmd)
255 248 ip.magic("macro test 1-3")
256 249 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
257 250
258 251 # List macros
259 252 nt.assert_in("test", ip.magic("macro"))
260 253
261 254
262 255 @dec.skip_without('sqlite3')
263 256 def test_macro_run():
264 257 """Test that we can run a multi-line macro successfully."""
265 258 ip = get_ipython()
266 259 ip.history_manager.reset()
267 260 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
268 261 "%macro test 2-3"]
269 262 for cmd in cmds:
270 263 ip.run_cell(cmd, store_history=True)
271 264 nt.assert_equal(ip.user_ns["test"].value,
272 265 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
273 266 with tt.AssertPrints("12"):
274 267 ip.run_cell("test")
275 268 with tt.AssertPrints("13"):
276 269 ip.run_cell("test")
277 270
278 271
279 272 def test_magic_magic():
280 273 """Test %magic"""
281 274 ip = get_ipython()
282 275 with capture_output() as captured:
283 276 ip.magic("magic")
284 277
285 278 stdout = captured.stdout
286 279 nt.assert_in('%magic', stdout)
287 280 nt.assert_in('IPython', stdout)
288 281 nt.assert_in('Available', stdout)
289 282
290 283
291 284 @dec.skipif_not_numpy
292 285 def test_numpy_reset_array_undec():
293 286 "Test '%reset array' functionality"
294 287 _ip.ex('import numpy as np')
295 288 _ip.ex('a = np.empty(2)')
296 289 nt.assert_in('a', _ip.user_ns)
297 290 _ip.magic('reset -f array')
298 291 nt.assert_not_in('a', _ip.user_ns)
299 292
300 293 def test_reset_out():
301 294 "Test '%reset out' magic"
302 295 _ip.run_cell("parrot = 'dead'", store_history=True)
303 296 # test '%reset -f out', make an Out prompt
304 297 _ip.run_cell("parrot", store_history=True)
305 298 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
306 299 _ip.magic('reset -f out')
307 300 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
308 301 nt.assert_equal(len(_ip.user_ns['Out']), 0)
309 302
310 303 def test_reset_in():
311 304 "Test '%reset in' magic"
312 305 # test '%reset -f in'
313 306 _ip.run_cell("parrot", store_history=True)
314 307 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
315 308 _ip.magic('%reset -f in')
316 309 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
317 310 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
318 311
319 312 def test_reset_dhist():
320 313 "Test '%reset dhist' magic"
321 314 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
322 315 _ip.magic('cd ' + os.path.dirname(nt.__file__))
323 316 _ip.magic('cd -')
324 317 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
325 318 _ip.magic('reset -f dhist')
326 319 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
327 320 _ip.run_cell("_dh = [d for d in tmp]") #restore
328 321
329 322 def test_reset_in_length():
330 323 "Test that '%reset in' preserves In[] length"
331 324 _ip.run_cell("print 'foo'")
332 325 _ip.run_cell("reset -f in")
333 326 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
334 327
335 328 def test_tb_syntaxerror():
336 329 """test %tb after a SyntaxError"""
337 330 ip = get_ipython()
338 331 ip.run_cell("for")
339 332
340 333 # trap and validate stdout
341 334 save_stdout = sys.stdout
342 335 try:
343 336 sys.stdout = StringIO()
344 337 ip.run_cell("%tb")
345 338 out = sys.stdout.getvalue()
346 339 finally:
347 340 sys.stdout = save_stdout
348 341 # trim output, and only check the last line
349 342 last_line = out.rstrip().splitlines()[-1].strip()
350 343 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
351 344
352 345
353 346 def test_time():
354 347 ip = get_ipython()
355 348
356 349 with tt.AssertPrints("Wall time: "):
357 350 ip.run_cell("%time None")
358 351
359 352 ip.run_cell("def f(kmjy):\n"
360 353 " %time print (2*kmjy)")
361 354
362 355 with tt.AssertPrints("Wall time: "):
363 356 with tt.AssertPrints("hihi", suppress=False):
364 357 ip.run_cell("f('hi')")
365 358
366 359
367 360 @dec.skip_win32
368 361 def test_time2():
369 362 ip = get_ipython()
370 363
371 364 with tt.AssertPrints("CPU times: user "):
372 365 ip.run_cell("%time None")
373 366
374 367 def test_time3():
375 368 """Erroneous magic function calls, issue gh-3334"""
376 369 ip = get_ipython()
377 370 ip.user_ns.pop('run', None)
378 371
379 372 with tt.AssertNotPrints("not found", channel='stderr'):
380 373 ip.run_cell("%%time\n"
381 374 "run = 0\n"
382 375 "run += 1")
383 376
384 377 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
385 378 def test_time_futures():
386 379 "Test %time with __future__ environments"
387 380 ip = get_ipython()
388 381 ip.autocall = 0
389 382 ip.run_cell("from __future__ import division")
390 383 with tt.AssertPrints('0.25'):
391 384 ip.run_line_magic('time', 'print(1/4)')
392 385 ip.compile.reset_compiler_flags()
393 386 with tt.AssertNotPrints('0.25'):
394 387 ip.run_line_magic('time', 'print(1/4)')
395 388
396 389 def test_doctest_mode():
397 390 "Toggle doctest_mode twice, it should be a no-op and run without error"
398 391 _ip.magic('doctest_mode')
399 392 _ip.magic('doctest_mode')
400 393
401 394
402 395 def test_parse_options():
403 396 """Tests for basic options parsing in magics."""
404 397 # These are only the most minimal of tests, more should be added later. At
405 398 # the very least we check that basic text/unicode calls work OK.
406 399 m = DummyMagics(_ip)
407 400 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
408 401 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
409 402
410 403
411 404 def test_dirops():
412 405 """Test various directory handling operations."""
413 406 # curpath = lambda :os.path.splitdrive(py3compat.getcwd())[1].replace('\\','/')
414 407 curpath = py3compat.getcwd
415 408 startdir = py3compat.getcwd()
416 409 ipdir = os.path.realpath(_ip.ipython_dir)
417 410 try:
418 411 _ip.magic('cd "%s"' % ipdir)
419 412 nt.assert_equal(curpath(), ipdir)
420 413 _ip.magic('cd -')
421 414 nt.assert_equal(curpath(), startdir)
422 415 _ip.magic('pushd "%s"' % ipdir)
423 416 nt.assert_equal(curpath(), ipdir)
424 417 _ip.magic('popd')
425 418 nt.assert_equal(curpath(), startdir)
426 419 finally:
427 420 os.chdir(startdir)
428 421
429 422
430 423 def test_xmode():
431 424 # Calling xmode three times should be a no-op
432 425 xmode = _ip.InteractiveTB.mode
433 426 for i in range(3):
434 427 _ip.magic("xmode")
435 428 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
436 429
437 430 def test_reset_hard():
438 431 monitor = []
439 432 class A(object):
440 433 def __del__(self):
441 434 monitor.append(1)
442 435 def __repr__(self):
443 436 return "<A instance>"
444 437
445 438 _ip.user_ns["a"] = A()
446 439 _ip.run_cell("a")
447 440
448 441 nt.assert_equal(monitor, [])
449 442 _ip.magic("reset -f")
450 443 nt.assert_equal(monitor, [1])
451 444
452 445 class TestXdel(tt.TempFileMixin):
453 446 def test_xdel(self):
454 447 """Test that references from %run are cleared by xdel."""
455 448 src = ("class A(object):\n"
456 449 " monitor = []\n"
457 450 " def __del__(self):\n"
458 451 " self.monitor.append(1)\n"
459 452 "a = A()\n")
460 453 self.mktmp(src)
461 454 # %run creates some hidden references...
462 455 _ip.magic("run %s" % self.fname)
463 456 # ... as does the displayhook.
464 457 _ip.run_cell("a")
465 458
466 459 monitor = _ip.user_ns["A"].monitor
467 460 nt.assert_equal(monitor, [])
468 461
469 462 _ip.magic("xdel a")
470 463
471 464 # Check that a's __del__ method has been called.
472 465 nt.assert_equal(monitor, [1])
473 466
474 467 def doctest_who():
475 468 """doctest for %who
476 469
477 470 In [1]: %reset -f
478 471
479 472 In [2]: alpha = 123
480 473
481 474 In [3]: beta = 'beta'
482 475
483 476 In [4]: %who int
484 477 alpha
485 478
486 479 In [5]: %who str
487 480 beta
488 481
489 482 In [6]: %whos
490 483 Variable Type Data/Info
491 484 ----------------------------
492 485 alpha int 123
493 486 beta str beta
494 487
495 488 In [7]: %who_ls
496 489 Out[7]: ['alpha', 'beta']
497 490 """
498 491
499 492 def test_whos():
500 493 """Check that whos is protected against objects where repr() fails."""
501 494 class A(object):
502 495 def __repr__(self):
503 496 raise Exception()
504 497 _ip.user_ns['a'] = A()
505 498 _ip.magic("whos")
506 499
507 500 @py3compat.u_format
508 501 def doctest_precision():
509 502 """doctest for %precision
510 503
511 504 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
512 505
513 506 In [2]: %precision 5
514 507 Out[2]: {u}'%.5f'
515 508
516 509 In [3]: f.float_format
517 510 Out[3]: {u}'%.5f'
518 511
519 512 In [4]: %precision %e
520 513 Out[4]: {u}'%e'
521 514
522 515 In [5]: f(3.1415927)
523 516 Out[5]: {u}'3.141593e+00'
524 517 """
525 518
526 519 def test_psearch():
527 520 with tt.AssertPrints("dict.fromkeys"):
528 521 _ip.run_cell("dict.fr*?")
529 522
530 523 def test_timeit_shlex():
531 524 """test shlex issues with timeit (#1109)"""
532 525 _ip.ex("def f(*a,**kw): pass")
533 526 _ip.magic('timeit -n1 "this is a bug".count(" ")')
534 527 _ip.magic('timeit -r1 -n1 f(" ", 1)')
535 528 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
536 529 _ip.magic('timeit -r1 -n1 ("a " + "b")')
537 530 _ip.magic('timeit -r1 -n1 f("a " + "b")')
538 531 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
539 532
540 533
541 534 def test_timeit_arguments():
542 535 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
543 536 _ip.magic("timeit ('#')")
544 537
545 538
546 539 def test_timeit_special_syntax():
547 540 "Test %%timeit with IPython special syntax"
548 541 @register_line_magic
549 542 def lmagic(line):
550 543 ip = get_ipython()
551 544 ip.user_ns['lmagic_out'] = line
552 545
553 546 # line mode test
554 547 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
555 548 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
556 549 # cell mode test
557 550 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
558 551 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
559 552
560 553 def test_timeit_return():
561 554 """
562 555 test wether timeit -o return object
563 556 """
564 557
565 558 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
566 559 assert(res is not None)
567 560
568 561 def test_timeit_quiet():
569 562 """
570 563 test quiet option of timeit magic
571 564 """
572 565 with tt.AssertNotPrints("loops"):
573 566 _ip.run_cell("%timeit -n1 -r1 -q 1")
574 567
575 568 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
576 569 def test_timeit_futures():
577 570 "Test %timeit with __future__ environments"
578 571 ip = get_ipython()
579 572 ip.run_cell("from __future__ import division")
580 573 with tt.AssertPrints('0.25'):
581 574 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
582 575 ip.compile.reset_compiler_flags()
583 576 with tt.AssertNotPrints('0.25'):
584 577 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
585 578
586 579 @dec.skipif(execution.profile is None)
587 580 def test_prun_special_syntax():
588 581 "Test %%prun with IPython special syntax"
589 582 @register_line_magic
590 583 def lmagic(line):
591 584 ip = get_ipython()
592 585 ip.user_ns['lmagic_out'] = line
593 586
594 587 # line mode test
595 588 _ip.run_line_magic('prun', '-q %lmagic my line')
596 589 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
597 590 # cell mode test
598 591 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
599 592 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
600 593
601 594 @dec.skipif(execution.profile is None)
602 595 def test_prun_quotes():
603 596 "Test that prun does not clobber string escapes (GH #1302)"
604 597 _ip.magic(r"prun -q x = '\t'")
605 598 nt.assert_equal(_ip.user_ns['x'], '\t')
606 599
607 600 def test_extension():
608 601 tmpdir = TemporaryDirectory()
609 602 orig_ipython_dir = _ip.ipython_dir
610 603 try:
611 604 _ip.ipython_dir = tmpdir.name
612 605 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
613 606 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
614 607 _ip.magic("install_ext %s" % url)
615 608 _ip.user_ns.pop('arq', None)
616 609 invalidate_caches() # Clear import caches
617 610 _ip.magic("load_ext daft_extension")
618 611 nt.assert_equal(_ip.user_ns['arq'], 185)
619 612 _ip.magic("unload_ext daft_extension")
620 613 assert 'arq' not in _ip.user_ns
621 614 finally:
622 615 _ip.ipython_dir = orig_ipython_dir
623 616 tmpdir.cleanup()
624 617
625 618
626 619 # The nose skip decorator doesn't work on classes, so this uses unittest's skipIf
627 @skipIf(dec.module_not_available('IPython.nbformat.current'), 'nbformat not importable')
620 @skipIf(dec.module_not_available('IPython.nbformat'), 'nbformat not importable')
628 621 class NotebookExportMagicTests(TestCase):
629 622 def test_notebook_export_json(self):
630 623 with TemporaryDirectory() as td:
631 624 outfile = os.path.join(td, "nb.ipynb")
632 625 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
633 626 _ip.magic("notebook -e %s" % outfile)
634 627
635 628
636 629 def test_env():
637 630 env = _ip.magic("env")
638 631 assert isinstance(env, dict), type(env)
639 632
640 633
641 634 class CellMagicTestCase(TestCase):
642 635
643 636 def check_ident(self, magic):
644 637 # Manually called, we get the result
645 638 out = _ip.run_cell_magic(magic, 'a', 'b')
646 639 nt.assert_equal(out, ('a','b'))
647 640 # Via run_cell, it goes into the user's namespace via displayhook
648 641 _ip.run_cell('%%' + magic +' c\nd')
649 642 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
650 643
651 644 def test_cell_magic_func_deco(self):
652 645 "Cell magic using simple decorator"
653 646 @register_cell_magic
654 647 def cellm(line, cell):
655 648 return line, cell
656 649
657 650 self.check_ident('cellm')
658 651
659 652 def test_cell_magic_reg(self):
660 653 "Cell magic manually registered"
661 654 def cellm(line, cell):
662 655 return line, cell
663 656
664 657 _ip.register_magic_function(cellm, 'cell', 'cellm2')
665 658 self.check_ident('cellm2')
666 659
667 660 def test_cell_magic_class(self):
668 661 "Cell magics declared via a class"
669 662 @magics_class
670 663 class MyMagics(Magics):
671 664
672 665 @cell_magic
673 666 def cellm3(self, line, cell):
674 667 return line, cell
675 668
676 669 _ip.register_magics(MyMagics)
677 670 self.check_ident('cellm3')
678 671
679 672 def test_cell_magic_class2(self):
680 673 "Cell magics declared via a class, #2"
681 674 @magics_class
682 675 class MyMagics2(Magics):
683 676
684 677 @cell_magic('cellm4')
685 678 def cellm33(self, line, cell):
686 679 return line, cell
687 680
688 681 _ip.register_magics(MyMagics2)
689 682 self.check_ident('cellm4')
690 683 # Check that nothing is registered as 'cellm33'
691 684 c33 = _ip.find_cell_magic('cellm33')
692 685 nt.assert_equal(c33, None)
693 686
694 687 def test_file():
695 688 """Basic %%file"""
696 689 ip = get_ipython()
697 690 with TemporaryDirectory() as td:
698 691 fname = os.path.join(td, 'file1')
699 692 ip.run_cell_magic("file", fname, u'\n'.join([
700 693 'line1',
701 694 'line2',
702 695 ]))
703 696 with open(fname) as f:
704 697 s = f.read()
705 698 nt.assert_in('line1\n', s)
706 699 nt.assert_in('line2', s)
707 700
708 701 def test_file_var_expand():
709 702 """%%file $filename"""
710 703 ip = get_ipython()
711 704 with TemporaryDirectory() as td:
712 705 fname = os.path.join(td, 'file1')
713 706 ip.user_ns['filename'] = fname
714 707 ip.run_cell_magic("file", '$filename', u'\n'.join([
715 708 'line1',
716 709 'line2',
717 710 ]))
718 711 with open(fname) as f:
719 712 s = f.read()
720 713 nt.assert_in('line1\n', s)
721 714 nt.assert_in('line2', s)
722 715
723 716 def test_file_unicode():
724 717 """%%file with unicode cell"""
725 718 ip = get_ipython()
726 719 with TemporaryDirectory() as td:
727 720 fname = os.path.join(td, 'file1')
728 721 ip.run_cell_magic("file", fname, u'\n'.join([
729 722 u'liné1',
730 723 u'liné2',
731 724 ]))
732 725 with io.open(fname, encoding='utf-8') as f:
733 726 s = f.read()
734 727 nt.assert_in(u'liné1\n', s)
735 728 nt.assert_in(u'liné2', s)
736 729
737 730 def test_file_amend():
738 731 """%%file -a amends files"""
739 732 ip = get_ipython()
740 733 with TemporaryDirectory() as td:
741 734 fname = os.path.join(td, 'file2')
742 735 ip.run_cell_magic("file", fname, u'\n'.join([
743 736 'line1',
744 737 'line2',
745 738 ]))
746 739 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
747 740 'line3',
748 741 'line4',
749 742 ]))
750 743 with open(fname) as f:
751 744 s = f.read()
752 745 nt.assert_in('line1\n', s)
753 746 nt.assert_in('line3\n', s)
754 747
755 748
756 749 def test_script_config():
757 750 ip = get_ipython()
758 751 ip.config.ScriptMagics.script_magics = ['whoda']
759 752 sm = script.ScriptMagics(shell=ip)
760 753 nt.assert_in('whoda', sm.magics['cell'])
761 754
762 755 @dec.skip_win32
763 756 def test_script_out():
764 757 ip = get_ipython()
765 758 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
766 759 nt.assert_equal(ip.user_ns['output'], 'hi\n')
767 760
768 761 @dec.skip_win32
769 762 def test_script_err():
770 763 ip = get_ipython()
771 764 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
772 765 nt.assert_equal(ip.user_ns['error'], 'hello\n')
773 766
774 767 @dec.skip_win32
775 768 def test_script_out_err():
776 769 ip = get_ipython()
777 770 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
778 771 nt.assert_equal(ip.user_ns['output'], 'hi\n')
779 772 nt.assert_equal(ip.user_ns['error'], 'hello\n')
780 773
781 774 @dec.skip_win32
782 775 def test_script_bg_out():
783 776 ip = get_ipython()
784 777 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
785 778 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
786 779
787 780 @dec.skip_win32
788 781 def test_script_bg_err():
789 782 ip = get_ipython()
790 783 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
791 784 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
792 785
793 786 @dec.skip_win32
794 787 def test_script_bg_out_err():
795 788 ip = get_ipython()
796 789 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
797 790 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
798 791 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
799 792
800 793 def test_script_defaults():
801 794 ip = get_ipython()
802 795 for cmd in ['sh', 'bash', 'perl', 'ruby']:
803 796 try:
804 797 find_cmd(cmd)
805 798 except Exception:
806 799 pass
807 800 else:
808 801 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
809 802
810 803
811 804 @magics_class
812 805 class FooFoo(Magics):
813 806 """class with both %foo and %%foo magics"""
814 807 @line_magic('foo')
815 808 def line_foo(self, line):
816 809 "I am line foo"
817 810 pass
818 811
819 812 @cell_magic("foo")
820 813 def cell_foo(self, line, cell):
821 814 "I am cell foo, not line foo"
822 815 pass
823 816
824 817 def test_line_cell_info():
825 818 """%%foo and %foo magics are distinguishable to inspect"""
826 819 ip = get_ipython()
827 820 ip.magics_manager.register(FooFoo)
828 821 oinfo = ip.object_inspect('foo')
829 822 nt.assert_true(oinfo['found'])
830 823 nt.assert_true(oinfo['ismagic'])
831 824
832 825 oinfo = ip.object_inspect('%%foo')
833 826 nt.assert_true(oinfo['found'])
834 827 nt.assert_true(oinfo['ismagic'])
835 828 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
836 829
837 830 oinfo = ip.object_inspect('%foo')
838 831 nt.assert_true(oinfo['found'])
839 832 nt.assert_true(oinfo['ismagic'])
840 833 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
841 834
842 835 def test_multiple_magics():
843 836 ip = get_ipython()
844 837 foo1 = FooFoo(ip)
845 838 foo2 = FooFoo(ip)
846 839 mm = ip.magics_manager
847 840 mm.register(foo1)
848 841 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
849 842 mm.register(foo2)
850 843 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
851 844
852 845 def test_alias_magic():
853 846 """Test %alias_magic."""
854 847 ip = get_ipython()
855 848 mm = ip.magics_manager
856 849
857 850 # Basic operation: both cell and line magics are created, if possible.
858 851 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
859 852 nt.assert_in('timeit_alias', mm.magics['line'])
860 853 nt.assert_in('timeit_alias', mm.magics['cell'])
861 854
862 855 # --cell is specified, line magic not created.
863 856 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
864 857 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
865 858 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
866 859
867 860 # Test that line alias is created successfully.
868 861 ip.run_line_magic('alias_magic', '--line env_alias env')
869 862 nt.assert_equal(ip.run_line_magic('env', ''),
870 863 ip.run_line_magic('env_alias', ''))
871 864
872 865 def test_save():
873 866 """Test %save."""
874 867 ip = get_ipython()
875 868 ip.history_manager.reset() # Clear any existing history.
876 869 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
877 870 for i, cmd in enumerate(cmds, start=1):
878 871 ip.history_manager.store_inputs(i, cmd)
879 872 with TemporaryDirectory() as tmpdir:
880 873 file = os.path.join(tmpdir, "testsave.py")
881 874 ip.run_line_magic("save", "%s 1-10" % file)
882 875 with open(file) as f:
883 876 content = f.read()
884 877 nt.assert_equal(content.count(cmds[0]), 1)
885 878 nt.assert_in('coding: utf-8', content)
886 879 ip.run_line_magic("save", "-a %s 1-10" % file)
887 880 with open(file) as f:
888 881 content = f.read()
889 882 nt.assert_equal(content.count(cmds[0]), 2)
890 883 nt.assert_in('coding: utf-8', content)
891 884
892 885
893 886 def test_store():
894 887 """Test %store."""
895 888 ip = get_ipython()
896 889 ip.run_line_magic('load_ext', 'storemagic')
897 890
898 891 # make sure the storage is empty
899 892 ip.run_line_magic('store', '-z')
900 893 ip.user_ns['var'] = 42
901 894 ip.run_line_magic('store', 'var')
902 895 ip.user_ns['var'] = 39
903 896 ip.run_line_magic('store', '-r')
904 897 nt.assert_equal(ip.user_ns['var'], 42)
905 898
906 899 ip.run_line_magic('store', '-d var')
907 900 ip.user_ns['var'] = 39
908 901 ip.run_line_magic('store' , '-r')
909 902 nt.assert_equal(ip.user_ns['var'], 39)
910 903
911 904
912 905 def _run_edit_test(arg_s, exp_filename=None,
913 906 exp_lineno=-1,
914 907 exp_contents=None,
915 908 exp_is_temp=None):
916 909 ip = get_ipython()
917 910 M = code.CodeMagics(ip)
918 911 last_call = ['','']
919 912 opts,args = M.parse_options(arg_s,'prxn:')
920 913 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
921 914
922 915 if exp_filename is not None:
923 916 nt.assert_equal(exp_filename, filename)
924 917 if exp_contents is not None:
925 918 with io.open(filename, 'r', encoding='utf-8') as f:
926 919 contents = f.read()
927 920 nt.assert_equal(exp_contents, contents)
928 921 if exp_lineno != -1:
929 922 nt.assert_equal(exp_lineno, lineno)
930 923 if exp_is_temp is not None:
931 924 nt.assert_equal(exp_is_temp, is_temp)
932 925
933 926
934 927 def test_edit_interactive():
935 928 """%edit on interactively defined objects"""
936 929 ip = get_ipython()
937 930 n = ip.execution_count
938 931 ip.run_cell(u"def foo(): return 1", store_history=True)
939 932
940 933 try:
941 934 _run_edit_test("foo")
942 935 except code.InteractivelyDefined as e:
943 936 nt.assert_equal(e.index, n)
944 937 else:
945 938 raise AssertionError("Should have raised InteractivelyDefined")
946 939
947 940
948 941 def test_edit_cell():
949 942 """%edit [cell id]"""
950 943 ip = get_ipython()
951 944
952 945 ip.run_cell(u"def foo(): return 1", store_history=True)
953 946
954 947 # test
955 948 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
956 949
957 950 def test_bookmark():
958 951 ip = get_ipython()
959 952 ip.run_line_magic('bookmark', 'bmname')
960 953 with tt.AssertPrints('bmname'):
961 954 ip.run_line_magic('bookmark', '-l')
962 955 ip.run_line_magic('bookmark', '-d bmname')
@@ -1,514 +1,512 b''
1 1 # encoding: utf-8
2 2 """Tests for code execution (%run and related), which is particularly tricky.
3 3
4 4 Because of how %run manages namespaces, and the fact that we are trying here to
5 5 verify subtle object deletion and reference counting issues, the %run tests
6 6 will be kept in this separate file. This makes it easier to aggregate in one
7 7 place the tricks needed to handle it; most other magics are much easier to test
8 8 and we do so in a common test_magic file.
9 9 """
10
11 # Copyright (c) IPython Development Team.
12 # Distributed under the terms of the Modified BSD License.
13
10 14 from __future__ import absolute_import
11 15
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15 16
16 17 import functools
17 18 import os
18 19 from os.path import join as pjoin
19 20 import random
20 21 import sys
21 22 import tempfile
22 23 import textwrap
23 24 import unittest
24 25
25 26 import nose.tools as nt
26 27 from nose import SkipTest
27 28
28 29 from IPython.testing import decorators as dec
29 30 from IPython.testing import tools as tt
30 31 from IPython.utils import py3compat
31 32 from IPython.utils.io import capture_output
32 33 from IPython.utils.tempdir import TemporaryDirectory
33 34 from IPython.core import debugger
34 35
35 #-----------------------------------------------------------------------------
36 # Test functions begin
37 #-----------------------------------------------------------------------------
38 36
39 37 def doctest_refbug():
40 38 """Very nasty problem with references held by multiple runs of a script.
41 39 See: https://github.com/ipython/ipython/issues/141
42 40
43 41 In [1]: _ip.clear_main_mod_cache()
44 42 # random
45 43
46 44 In [2]: %run refbug
47 45
48 46 In [3]: call_f()
49 47 lowercased: hello
50 48
51 49 In [4]: %run refbug
52 50
53 51 In [5]: call_f()
54 52 lowercased: hello
55 53 lowercased: hello
56 54 """
57 55
58 56
59 57 def doctest_run_builtins():
60 58 r"""Check that %run doesn't damage __builtins__.
61 59
62 60 In [1]: import tempfile
63 61
64 62 In [2]: bid1 = id(__builtins__)
65 63
66 64 In [3]: fname = tempfile.mkstemp('.py')[1]
67 65
68 66 In [3]: f = open(fname,'w')
69 67
70 68 In [4]: dummy= f.write('pass\n')
71 69
72 70 In [5]: f.flush()
73 71
74 72 In [6]: t1 = type(__builtins__)
75 73
76 74 In [7]: %run $fname
77 75
78 76 In [7]: f.close()
79 77
80 78 In [8]: bid2 = id(__builtins__)
81 79
82 80 In [9]: t2 = type(__builtins__)
83 81
84 82 In [10]: t1 == t2
85 83 Out[10]: True
86 84
87 85 In [10]: bid1 == bid2
88 86 Out[10]: True
89 87
90 88 In [12]: try:
91 89 ....: os.unlink(fname)
92 90 ....: except:
93 91 ....: pass
94 92 ....:
95 93 """
96 94
97 95
98 96 def doctest_run_option_parser():
99 97 r"""Test option parser in %run.
100 98
101 99 In [1]: %run print_argv.py
102 100 []
103 101
104 102 In [2]: %run print_argv.py print*.py
105 103 ['print_argv.py']
106 104
107 105 In [3]: %run -G print_argv.py print*.py
108 106 ['print*.py']
109 107
110 108 """
111 109
112 110
113 111 @dec.skip_win32
114 112 def doctest_run_option_parser_for_posix():
115 113 r"""Test option parser in %run (Linux/OSX specific).
116 114
117 115 You need double quote to escape glob in POSIX systems:
118 116
119 117 In [1]: %run print_argv.py print\\*.py
120 118 ['print*.py']
121 119
122 120 You can't use quote to escape glob in POSIX systems:
123 121
124 122 In [2]: %run print_argv.py 'print*.py'
125 123 ['print_argv.py']
126 124
127 125 """
128 126
129 127
130 128 @dec.skip_if_not_win32
131 129 def doctest_run_option_parser_for_windows():
132 130 r"""Test option parser in %run (Windows specific).
133 131
134 132 In Windows, you can't escape ``*` `by backslash:
135 133
136 134 In [1]: %run print_argv.py print\\*.py
137 135 ['print\\*.py']
138 136
139 137 You can use quote to escape glob:
140 138
141 139 In [2]: %run print_argv.py 'print*.py'
142 140 ['print*.py']
143 141
144 142 """
145 143
146 144
147 145 @py3compat.doctest_refactor_print
148 146 def doctest_reset_del():
149 147 """Test that resetting doesn't cause errors in __del__ methods.
150 148
151 149 In [2]: class A(object):
152 150 ...: def __del__(self):
153 151 ...: print str("Hi")
154 152 ...:
155 153
156 154 In [3]: a = A()
157 155
158 156 In [4]: get_ipython().reset()
159 157 Hi
160 158
161 159 In [5]: 1+1
162 160 Out[5]: 2
163 161 """
164 162
165 163 # For some tests, it will be handy to organize them in a class with a common
166 164 # setup that makes a temp file
167 165
168 166 class TestMagicRunPass(tt.TempFileMixin):
169 167
170 168 def setup(self):
171 169 """Make a valid python temp file."""
172 170 self.mktmp('pass\n')
173 171
174 172 def run_tmpfile(self):
175 173 _ip = get_ipython()
176 174 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
177 175 # See below and ticket https://bugs.launchpad.net/bugs/366353
178 176 _ip.magic('run %s' % self.fname)
179 177
180 178 def run_tmpfile_p(self):
181 179 _ip = get_ipython()
182 180 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
183 181 # See below and ticket https://bugs.launchpad.net/bugs/366353
184 182 _ip.magic('run -p %s' % self.fname)
185 183
186 184 def test_builtins_id(self):
187 185 """Check that %run doesn't damage __builtins__ """
188 186 _ip = get_ipython()
189 187 # Test that the id of __builtins__ is not modified by %run
190 188 bid1 = id(_ip.user_ns['__builtins__'])
191 189 self.run_tmpfile()
192 190 bid2 = id(_ip.user_ns['__builtins__'])
193 191 nt.assert_equal(bid1, bid2)
194 192
195 193 def test_builtins_type(self):
196 194 """Check that the type of __builtins__ doesn't change with %run.
197 195
198 196 However, the above could pass if __builtins__ was already modified to
199 197 be a dict (it should be a module) by a previous use of %run. So we
200 198 also check explicitly that it really is a module:
201 199 """
202 200 _ip = get_ipython()
203 201 self.run_tmpfile()
204 202 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
205 203
206 204 def test_prompts(self):
207 205 """Test that prompts correctly generate after %run"""
208 206 self.run_tmpfile()
209 207 _ip = get_ipython()
210 208 p2 = _ip.prompt_manager.render('in2').strip()
211 209 nt.assert_equal(p2[:3], '...')
212 210
213 211 def test_run_profile( self ):
214 212 """Test that the option -p, which invokes the profiler, do not
215 213 crash by invoking execfile"""
216 214 _ip = get_ipython()
217 215 self.run_tmpfile_p()
218 216
219 217
220 218 class TestMagicRunSimple(tt.TempFileMixin):
221 219
222 220 def test_simpledef(self):
223 221 """Test that simple class definitions work."""
224 222 src = ("class foo: pass\n"
225 223 "def f(): return foo()")
226 224 self.mktmp(src)
227 225 _ip.magic('run %s' % self.fname)
228 226 _ip.run_cell('t = isinstance(f(), foo)')
229 227 nt.assert_true(_ip.user_ns['t'])
230 228
231 229 def test_obj_del(self):
232 230 """Test that object's __del__ methods are called on exit."""
233 231 if sys.platform == 'win32':
234 232 try:
235 233 import win32api
236 234 except ImportError:
237 235 raise SkipTest("Test requires pywin32")
238 236 src = ("class A(object):\n"
239 237 " def __del__(self):\n"
240 238 " print 'object A deleted'\n"
241 239 "a = A()\n")
242 240 self.mktmp(py3compat.doctest_refactor_print(src))
243 241 if dec.module_not_available('sqlite3'):
244 242 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
245 243 else:
246 244 err = None
247 245 tt.ipexec_validate(self.fname, 'object A deleted', err)
248 246
249 247 def test_aggressive_namespace_cleanup(self):
250 248 """Test that namespace cleanup is not too aggressive GH-238
251 249
252 250 Returning from another run magic deletes the namespace"""
253 251 # see ticket https://github.com/ipython/ipython/issues/238
254 252 class secondtmp(tt.TempFileMixin): pass
255 253 empty = secondtmp()
256 254 empty.mktmp('')
257 255 # On Windows, the filename will have \users in it, so we need to use the
258 256 # repr so that the \u becomes \\u.
259 257 src = ("ip = get_ipython()\n"
260 258 "for i in range(5):\n"
261 259 " try:\n"
262 260 " ip.magic(%r)\n"
263 261 " except NameError as e:\n"
264 262 " print(i)\n"
265 263 " break\n" % ('run ' + empty.fname))
266 264 self.mktmp(src)
267 265 _ip.magic('run %s' % self.fname)
268 266 _ip.run_cell('ip == get_ipython()')
269 267 nt.assert_equal(_ip.user_ns['i'], 4)
270 268
271 269 def test_run_second(self):
272 270 """Test that running a second file doesn't clobber the first, gh-3547
273 271 """
274 272 self.mktmp("avar = 1\n"
275 273 "def afunc():\n"
276 274 " return avar\n")
277 275
278 276 empty = tt.TempFileMixin()
279 277 empty.mktmp("")
280 278
281 279 _ip.magic('run %s' % self.fname)
282 280 _ip.magic('run %s' % empty.fname)
283 281 nt.assert_equal(_ip.user_ns['afunc'](), 1)
284 282
285 283 @dec.skip_win32
286 284 def test_tclass(self):
287 285 mydir = os.path.dirname(__file__)
288 286 tc = os.path.join(mydir, 'tclass')
289 287 src = ("%%run '%s' C-first\n"
290 288 "%%run '%s' C-second\n"
291 289 "%%run '%s' C-third\n") % (tc, tc, tc)
292 290 self.mktmp(src, '.ipy')
293 291 out = """\
294 292 ARGV 1-: ['C-first']
295 293 ARGV 1-: ['C-second']
296 294 tclass.py: deleting object: C-first
297 295 ARGV 1-: ['C-third']
298 296 tclass.py: deleting object: C-second
299 297 tclass.py: deleting object: C-third
300 298 """
301 299 if dec.module_not_available('sqlite3'):
302 300 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
303 301 else:
304 302 err = None
305 303 tt.ipexec_validate(self.fname, out, err)
306 304
307 305 def test_run_i_after_reset(self):
308 306 """Check that %run -i still works after %reset (gh-693)"""
309 307 src = "yy = zz\n"
310 308 self.mktmp(src)
311 309 _ip.run_cell("zz = 23")
312 310 _ip.magic('run -i %s' % self.fname)
313 311 nt.assert_equal(_ip.user_ns['yy'], 23)
314 312 _ip.magic('reset -f')
315 313 _ip.run_cell("zz = 23")
316 314 _ip.magic('run -i %s' % self.fname)
317 315 nt.assert_equal(_ip.user_ns['yy'], 23)
318 316
319 317 def test_unicode(self):
320 318 """Check that files in odd encodings are accepted."""
321 319 mydir = os.path.dirname(__file__)
322 320 na = os.path.join(mydir, 'nonascii.py')
323 321 _ip.magic('run "%s"' % na)
324 322 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
325 323
326 324 def test_run_py_file_attribute(self):
327 325 """Test handling of `__file__` attribute in `%run <file>.py`."""
328 326 src = "t = __file__\n"
329 327 self.mktmp(src)
330 328 _missing = object()
331 329 file1 = _ip.user_ns.get('__file__', _missing)
332 330 _ip.magic('run %s' % self.fname)
333 331 file2 = _ip.user_ns.get('__file__', _missing)
334 332
335 333 # Check that __file__ was equal to the filename in the script's
336 334 # namespace.
337 335 nt.assert_equal(_ip.user_ns['t'], self.fname)
338 336
339 337 # Check that __file__ was not leaked back into user_ns.
340 338 nt.assert_equal(file1, file2)
341 339
342 340 def test_run_ipy_file_attribute(self):
343 341 """Test handling of `__file__` attribute in `%run <file.ipy>`."""
344 342 src = "t = __file__\n"
345 343 self.mktmp(src, ext='.ipy')
346 344 _missing = object()
347 345 file1 = _ip.user_ns.get('__file__', _missing)
348 346 _ip.magic('run %s' % self.fname)
349 347 file2 = _ip.user_ns.get('__file__', _missing)
350 348
351 349 # Check that __file__ was equal to the filename in the script's
352 350 # namespace.
353 351 nt.assert_equal(_ip.user_ns['t'], self.fname)
354 352
355 353 # Check that __file__ was not leaked back into user_ns.
356 354 nt.assert_equal(file1, file2)
357 355
358 356 def test_run_formatting(self):
359 357 """ Test that %run -t -N<N> does not raise a TypeError for N > 1."""
360 358 src = "pass"
361 359 self.mktmp(src)
362 360 _ip.magic('run -t -N 1 %s' % self.fname)
363 361 _ip.magic('run -t -N 10 %s' % self.fname)
364 362
365 363 def test_ignore_sys_exit(self):
366 364 """Test the -e option to ignore sys.exit()"""
367 365 src = "import sys; sys.exit(1)"
368 366 self.mktmp(src)
369 367 with tt.AssertPrints('SystemExit'):
370 368 _ip.magic('run %s' % self.fname)
371 369
372 370 with tt.AssertNotPrints('SystemExit'):
373 371 _ip.magic('run -e %s' % self.fname)
374 372
375 @dec.skip_without('IPython.nbformat.current') # Requires jsonschema
373 @dec.skip_without('IPython.nbformat') # Requires jsonschema
376 374 def test_run_nb(self):
377 375 """Test %run notebook.ipynb"""
378 from IPython.nbformat import current
379 nb = current.new_notebook(
376 from IPython.nbformat import v4, writes
377 nb = v4.new_notebook(
380 378 cells=[
381 current.new_markdown_cell("The Ultimate Question of Everything"),
382 current.new_code_cell("answer=42")
379 v4.new_markdown_cell("The Ultimate Question of Everything"),
380 v4.new_code_cell("answer=42")
383 381 ]
384 382 )
385 src = current.writes(nb)
383 src = writes(nb, version=4)
386 384 self.mktmp(src, ext='.ipynb')
387 385
388 386 _ip.magic("run %s" % self.fname)
389 387
390 388 nt.assert_equal(_ip.user_ns['answer'], 42)
391 389
392 390
393 391
394 392 class TestMagicRunWithPackage(unittest.TestCase):
395 393
396 394 def writefile(self, name, content):
397 395 path = os.path.join(self.tempdir.name, name)
398 396 d = os.path.dirname(path)
399 397 if not os.path.isdir(d):
400 398 os.makedirs(d)
401 399 with open(path, 'w') as f:
402 400 f.write(textwrap.dedent(content))
403 401
404 402 def setUp(self):
405 403 self.package = package = 'tmp{0}'.format(repr(random.random())[2:])
406 404 """Temporary valid python package name."""
407 405
408 406 self.value = int(random.random() * 10000)
409 407
410 408 self.tempdir = TemporaryDirectory()
411 409 self.__orig_cwd = py3compat.getcwd()
412 410 sys.path.insert(0, self.tempdir.name)
413 411
414 412 self.writefile(os.path.join(package, '__init__.py'), '')
415 413 self.writefile(os.path.join(package, 'sub.py'), """
416 414 x = {0!r}
417 415 """.format(self.value))
418 416 self.writefile(os.path.join(package, 'relative.py'), """
419 417 from .sub import x
420 418 """)
421 419 self.writefile(os.path.join(package, 'absolute.py'), """
422 420 from {0}.sub import x
423 421 """.format(package))
424 422
425 423 def tearDown(self):
426 424 os.chdir(self.__orig_cwd)
427 425 sys.path[:] = [p for p in sys.path if p != self.tempdir.name]
428 426 self.tempdir.cleanup()
429 427
430 428 def check_run_submodule(self, submodule, opts=''):
431 429 _ip.user_ns.pop('x', None)
432 430 _ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts))
433 431 self.assertEqual(_ip.user_ns['x'], self.value,
434 432 'Variable `x` is not loaded from module `{0}`.'
435 433 .format(submodule))
436 434
437 435 def test_run_submodule_with_absolute_import(self):
438 436 self.check_run_submodule('absolute')
439 437
440 438 def test_run_submodule_with_relative_import(self):
441 439 """Run submodule that has a relative import statement (#2727)."""
442 440 self.check_run_submodule('relative')
443 441
444 442 def test_prun_submodule_with_absolute_import(self):
445 443 self.check_run_submodule('absolute', '-p')
446 444
447 445 def test_prun_submodule_with_relative_import(self):
448 446 self.check_run_submodule('relative', '-p')
449 447
450 448 def with_fake_debugger(func):
451 449 @functools.wraps(func)
452 450 def wrapper(*args, **kwds):
453 451 with tt.monkeypatch(debugger.Pdb, 'run', staticmethod(eval)):
454 452 return func(*args, **kwds)
455 453 return wrapper
456 454
457 455 @with_fake_debugger
458 456 def test_debug_run_submodule_with_absolute_import(self):
459 457 self.check_run_submodule('absolute', '-d')
460 458
461 459 @with_fake_debugger
462 460 def test_debug_run_submodule_with_relative_import(self):
463 461 self.check_run_submodule('relative', '-d')
464 462
465 463 def test_run__name__():
466 464 with TemporaryDirectory() as td:
467 465 path = pjoin(td, 'foo.py')
468 466 with open(path, 'w') as f:
469 467 f.write("q = __name__")
470 468
471 469 _ip.user_ns.pop('q', None)
472 470 _ip.magic('run {}'.format(path))
473 471 nt.assert_equal(_ip.user_ns.pop('q'), '__main__')
474 472
475 473 _ip.magic('run -n {}'.format(path))
476 474 nt.assert_equal(_ip.user_ns.pop('q'), 'foo')
477 475
478 476 def test_run_tb():
479 477 """Test traceback offset in %run"""
480 478 with TemporaryDirectory() as td:
481 479 path = pjoin(td, 'foo.py')
482 480 with open(path, 'w') as f:
483 481 f.write('\n'.join([
484 482 "def foo():",
485 483 " return bar()",
486 484 "def bar():",
487 485 " raise RuntimeError('hello!')",
488 486 "foo()",
489 487 ]))
490 488 with capture_output() as io:
491 489 _ip.magic('run {}'.format(path))
492 490 out = io.stdout
493 491 nt.assert_not_in("execfile", out)
494 492 nt.assert_in("RuntimeError", out)
495 493 nt.assert_equal(out.count("---->"), 3)
496 494
497 495 @dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows")
498 496 def test_script_tb():
499 497 """Test traceback offset in `ipython script.py`"""
500 498 with TemporaryDirectory() as td:
501 499 path = pjoin(td, 'foo.py')
502 500 with open(path, 'w') as f:
503 501 f.write('\n'.join([
504 502 "def foo():",
505 503 " return bar()",
506 504 "def bar():",
507 505 " raise RuntimeError('hello!')",
508 506 "foo()",
509 507 ]))
510 508 out, err = tt.ipexec(path)
511 509 nt.assert_not_in("execfile", out)
512 510 nt.assert_in("RuntimeError", out)
513 511 nt.assert_equal(out.count("---->"), 3)
514 512
@@ -1,42 +1,30 b''
1 1 """Test help output of various IPython entry points"""
2 2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
13 5
14 6 import IPython.testing.tools as tt
15 7 from IPython.testing.decorators import skip_without
16 8
17 #-----------------------------------------------------------------------------
18 # Tests
19 #-----------------------------------------------------------------------------
20
21 9
22 10 def test_ipython_help():
23 11 tt.help_all_output_test()
24 12
25 13 def test_profile_help():
26 14 tt.help_all_output_test("profile")
27 15
28 16 def test_profile_list_help():
29 17 tt.help_all_output_test("profile list")
30 18
31 19 def test_profile_create_help():
32 20 tt.help_all_output_test("profile create")
33 21
34 22 def test_locate_help():
35 23 tt.help_all_output_test("locate")
36 24
37 25 def test_locate_profile_help():
38 26 tt.help_all_output_test("locate profile")
39 27
40 @skip_without('IPython.nbformat.current') # Requires jsonschema to be installed
28 @skip_without('IPython.nbformat') # Requires jsonschema to be installed
41 29 def test_trust_help():
42 30 tt.help_all_output_test("trust")
General Comments 0
You need to be logged in to leave comments. Login now