##// END OF EJS Templates
add time test
Matthias Bussonnier -
Show More
@@ -1,1170 +1,1179 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 importlib import invalidate_caches
15 15 from io import StringIO
16 16
17 17 import nose.tools as nt
18 18
19 19 import shlex
20 20
21 21 from IPython import get_ipython
22 22 from IPython.core import magic
23 23 from IPython.core.error import UsageError
24 24 from IPython.core.magic import (Magics, magics_class, line_magic,
25 25 cell_magic,
26 26 register_line_magic, register_cell_magic)
27 27 from IPython.core.magics import execution, script, code, logging, osm
28 28 from IPython.testing import decorators as dec
29 29 from IPython.testing import tools as tt
30 30 from IPython.utils.io import capture_output
31 31 from IPython.utils.tempdir import (TemporaryDirectory,
32 32 TemporaryWorkingDirectory)
33 33 from IPython.utils.process import find_cmd
34 34
35 35
36 36 @magic.magics_class
37 37 class DummyMagics(magic.Magics): pass
38 38
39 39 def test_extract_code_ranges():
40 40 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
41 41 expected = [(0, 1),
42 42 (2, 3),
43 43 (4, 6),
44 44 (6, 9),
45 45 (9, 14),
46 46 (16, None),
47 47 (None, 9),
48 48 (9, None),
49 49 (None, 13),
50 50 (None, None)]
51 51 actual = list(code.extract_code_ranges(instr))
52 52 nt.assert_equal(actual, expected)
53 53
54 54 def test_extract_symbols():
55 55 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
56 56 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
57 57 expected = [([], ['a']),
58 58 (["def b():\n return 42\n"], []),
59 59 (["class A: pass\n"], []),
60 60 (["class A: pass\n", "def b():\n return 42\n"], []),
61 61 (["class A: pass\n"], ['a']),
62 62 ([], ['z'])]
63 63 for symbols, exp in zip(symbols_args, expected):
64 64 nt.assert_equal(code.extract_symbols(source, symbols), exp)
65 65
66 66
67 67 def test_extract_symbols_raises_exception_with_non_python_code():
68 68 source = ("=begin A Ruby program :)=end\n"
69 69 "def hello\n"
70 70 "puts 'Hello world'\n"
71 71 "end")
72 72 with nt.assert_raises(SyntaxError):
73 73 code.extract_symbols(source, "hello")
74 74
75 75
76 76 def test_magic_not_found():
77 77 # magic not found raises UsageError
78 78 with nt.assert_raises(UsageError):
79 79 _ip.magic('doesntexist')
80 80
81 81 # ensure result isn't success when a magic isn't found
82 82 result = _ip.run_cell('%doesntexist')
83 83 assert isinstance(result.error_in_exec, UsageError)
84 84
85 85
86 86 def test_cell_magic_not_found():
87 87 # magic not found raises UsageError
88 88 with nt.assert_raises(UsageError):
89 89 _ip.run_cell_magic('doesntexist', 'line', 'cell')
90 90
91 91 # ensure result isn't success when a magic isn't found
92 92 result = _ip.run_cell('%%doesntexist')
93 93 assert isinstance(result.error_in_exec, UsageError)
94 94
95 95
96 96 def test_magic_error_status():
97 97 def fail(shell):
98 98 1/0
99 99 _ip.register_magic_function(fail)
100 100 result = _ip.run_cell('%fail')
101 101 assert isinstance(result.error_in_exec, ZeroDivisionError)
102 102
103 103
104 104 def test_config():
105 105 """ test that config magic does not raise
106 106 can happen if Configurable init is moved too early into
107 107 Magics.__init__ as then a Config object will be registered as a
108 108 magic.
109 109 """
110 110 ## should not raise.
111 111 _ip.magic('config')
112 112
113 113 def test_config_available_configs():
114 114 """ test that config magic prints available configs in unique and
115 115 sorted order. """
116 116 with capture_output() as captured:
117 117 _ip.magic('config')
118 118
119 119 stdout = captured.stdout
120 120 config_classes = stdout.strip().split('\n')[1:]
121 121 nt.assert_list_equal(config_classes, sorted(set(config_classes)))
122 122
123 123 def test_config_print_class():
124 124 """ test that config with a classname prints the class's options. """
125 125 with capture_output() as captured:
126 126 _ip.magic('config TerminalInteractiveShell')
127 127
128 128 stdout = captured.stdout
129 129 if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]):
130 130 print(stdout)
131 131 raise AssertionError("1st line of stdout not like "
132 132 "'TerminalInteractiveShell.* options'")
133 133
134 134 def test_rehashx():
135 135 # clear up everything
136 136 _ip.alias_manager.clear_aliases()
137 137 del _ip.db['syscmdlist']
138 138
139 139 _ip.magic('rehashx')
140 140 # Practically ALL ipython development systems will have more than 10 aliases
141 141
142 142 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
143 143 for name, cmd in _ip.alias_manager.aliases:
144 144 # we must strip dots from alias names
145 145 nt.assert_not_in('.', name)
146 146
147 147 # rehashx must fill up syscmdlist
148 148 scoms = _ip.db['syscmdlist']
149 149 nt.assert_true(len(scoms) > 10)
150 150
151 151
152 152
153 153 def test_magic_parse_options():
154 154 """Test that we don't mangle paths when parsing magic options."""
155 155 ip = get_ipython()
156 156 path = 'c:\\x'
157 157 m = DummyMagics(ip)
158 158 opts = m.parse_options('-f %s' % path,'f:')[0]
159 159 # argv splitting is os-dependent
160 160 if os.name == 'posix':
161 161 expected = 'c:x'
162 162 else:
163 163 expected = path
164 164 nt.assert_equal(opts['f'], expected)
165 165
166 166 def test_magic_parse_long_options():
167 167 """Magic.parse_options can handle --foo=bar long options"""
168 168 ip = get_ipython()
169 169 m = DummyMagics(ip)
170 170 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
171 171 nt.assert_in('foo', opts)
172 172 nt.assert_in('bar', opts)
173 173 nt.assert_equal(opts['bar'], "bubble")
174 174
175 175
176 176 @dec.skip_without('sqlite3')
177 177 def doctest_hist_f():
178 178 """Test %hist -f with temporary filename.
179 179
180 180 In [9]: import tempfile
181 181
182 182 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
183 183
184 184 In [11]: %hist -nl -f $tfile 3
185 185
186 186 In [13]: import os; os.unlink(tfile)
187 187 """
188 188
189 189
190 190 @dec.skip_without('sqlite3')
191 191 def doctest_hist_r():
192 192 """Test %hist -r
193 193
194 194 XXX - This test is not recording the output correctly. For some reason, in
195 195 testing mode the raw history isn't getting populated. No idea why.
196 196 Disabling the output checking for now, though at least we do run it.
197 197
198 198 In [1]: 'hist' in _ip.lsmagic()
199 199 Out[1]: True
200 200
201 201 In [2]: x=1
202 202
203 203 In [3]: %hist -rl 2
204 204 x=1 # random
205 205 %hist -r 2
206 206 """
207 207
208 208
209 209 @dec.skip_without('sqlite3')
210 210 def doctest_hist_op():
211 211 """Test %hist -op
212 212
213 213 In [1]: class b(float):
214 214 ...: pass
215 215 ...:
216 216
217 217 In [2]: class s(object):
218 218 ...: def __str__(self):
219 219 ...: return 's'
220 220 ...:
221 221
222 222 In [3]:
223 223
224 224 In [4]: class r(b):
225 225 ...: def __repr__(self):
226 226 ...: return 'r'
227 227 ...:
228 228
229 229 In [5]: class sr(s,r): pass
230 230 ...:
231 231
232 232 In [6]:
233 233
234 234 In [7]: bb=b()
235 235
236 236 In [8]: ss=s()
237 237
238 238 In [9]: rr=r()
239 239
240 240 In [10]: ssrr=sr()
241 241
242 242 In [11]: 4.5
243 243 Out[11]: 4.5
244 244
245 245 In [12]: str(ss)
246 246 Out[12]: 's'
247 247
248 248 In [13]:
249 249
250 250 In [14]: %hist -op
251 251 >>> class b:
252 252 ... pass
253 253 ...
254 254 >>> class s(b):
255 255 ... def __str__(self):
256 256 ... return 's'
257 257 ...
258 258 >>>
259 259 >>> class r(b):
260 260 ... def __repr__(self):
261 261 ... return 'r'
262 262 ...
263 263 >>> class sr(s,r): pass
264 264 >>>
265 265 >>> bb=b()
266 266 >>> ss=s()
267 267 >>> rr=r()
268 268 >>> ssrr=sr()
269 269 >>> 4.5
270 270 4.5
271 271 >>> str(ss)
272 272 's'
273 273 >>>
274 274 """
275 275
276 276 def test_hist_pof():
277 277 ip = get_ipython()
278 278 ip.run_cell(u"1+2", store_history=True)
279 279 #raise Exception(ip.history_manager.session_number)
280 280 #raise Exception(list(ip.history_manager._get_range_session()))
281 281 with TemporaryDirectory() as td:
282 282 tf = os.path.join(td, 'hist.py')
283 283 ip.run_line_magic('history', '-pof %s' % tf)
284 284 assert os.path.isfile(tf)
285 285
286 286
287 287 @dec.skip_without('sqlite3')
288 288 def test_macro():
289 289 ip = get_ipython()
290 290 ip.history_manager.reset() # Clear any existing history.
291 291 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
292 292 for i, cmd in enumerate(cmds, start=1):
293 293 ip.history_manager.store_inputs(i, cmd)
294 294 ip.magic("macro test 1-3")
295 295 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
296 296
297 297 # List macros
298 298 nt.assert_in("test", ip.magic("macro"))
299 299
300 300
301 301 @dec.skip_without('sqlite3')
302 302 def test_macro_run():
303 303 """Test that we can run a multi-line macro successfully."""
304 304 ip = get_ipython()
305 305 ip.history_manager.reset()
306 306 cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"]
307 307 for cmd in cmds:
308 308 ip.run_cell(cmd, store_history=True)
309 309 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint(a)\n")
310 310 with tt.AssertPrints("12"):
311 311 ip.run_cell("test")
312 312 with tt.AssertPrints("13"):
313 313 ip.run_cell("test")
314 314
315 315
316 316 def test_magic_magic():
317 317 """Test %magic"""
318 318 ip = get_ipython()
319 319 with capture_output() as captured:
320 320 ip.magic("magic")
321 321
322 322 stdout = captured.stdout
323 323 nt.assert_in('%magic', stdout)
324 324 nt.assert_in('IPython', stdout)
325 325 nt.assert_in('Available', stdout)
326 326
327 327
328 328 @dec.skipif_not_numpy
329 329 def test_numpy_reset_array_undec():
330 330 "Test '%reset array' functionality"
331 331 _ip.ex('import numpy as np')
332 332 _ip.ex('a = np.empty(2)')
333 333 nt.assert_in('a', _ip.user_ns)
334 334 _ip.magic('reset -f array')
335 335 nt.assert_not_in('a', _ip.user_ns)
336 336
337 337 def test_reset_out():
338 338 "Test '%reset out' magic"
339 339 _ip.run_cell("parrot = 'dead'", store_history=True)
340 340 # test '%reset -f out', make an Out prompt
341 341 _ip.run_cell("parrot", store_history=True)
342 342 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
343 343 _ip.magic('reset -f out')
344 344 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
345 345 nt.assert_equal(len(_ip.user_ns['Out']), 0)
346 346
347 347 def test_reset_in():
348 348 "Test '%reset in' magic"
349 349 # test '%reset -f in'
350 350 _ip.run_cell("parrot", store_history=True)
351 351 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
352 352 _ip.magic('%reset -f in')
353 353 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
354 354 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
355 355
356 356 def test_reset_dhist():
357 357 "Test '%reset dhist' magic"
358 358 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
359 359 _ip.magic('cd ' + os.path.dirname(nt.__file__))
360 360 _ip.magic('cd -')
361 361 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
362 362 _ip.magic('reset -f dhist')
363 363 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
364 364 _ip.run_cell("_dh = [d for d in tmp]") #restore
365 365
366 366 def test_reset_in_length():
367 367 "Test that '%reset in' preserves In[] length"
368 368 _ip.run_cell("print 'foo'")
369 369 _ip.run_cell("reset -f in")
370 370 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
371 371
372 372 def test_tb_syntaxerror():
373 373 """test %tb after a SyntaxError"""
374 374 ip = get_ipython()
375 375 ip.run_cell("for")
376 376
377 377 # trap and validate stdout
378 378 save_stdout = sys.stdout
379 379 try:
380 380 sys.stdout = StringIO()
381 381 ip.run_cell("%tb")
382 382 out = sys.stdout.getvalue()
383 383 finally:
384 384 sys.stdout = save_stdout
385 385 # trim output, and only check the last line
386 386 last_line = out.rstrip().splitlines()[-1].strip()
387 387 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
388 388
389 389
390 390 def test_time():
391 391 ip = get_ipython()
392 392
393 393 with tt.AssertPrints("Wall time: "):
394 394 ip.run_cell("%time None")
395 395
396 396 ip.run_cell("def f(kmjy):\n"
397 397 " %time print (2*kmjy)")
398 398
399 399 with tt.AssertPrints("Wall time: "):
400 400 with tt.AssertPrints("hihi", suppress=False):
401 401 ip.run_cell("f('hi')")
402 402
403 def test_time_last_not_expression():
404 ip.run_cell("%%time\n"
405 "var_1 = 1\n"
406 "var_2 = 2\n")
407 assert ip.user_ns['var_1'] == 1
408 del ip.user_ns['var_1']
409 assert ip.user_ns['var_2'] == 2
410 del ip.user_ns['var_2']
411
403 412
404 413 @dec.skip_win32
405 414 def test_time2():
406 415 ip = get_ipython()
407 416
408 417 with tt.AssertPrints("CPU times: user "):
409 418 ip.run_cell("%time None")
410 419
411 420 def test_time3():
412 421 """Erroneous magic function calls, issue gh-3334"""
413 422 ip = get_ipython()
414 423 ip.user_ns.pop('run', None)
415 424
416 425 with tt.AssertNotPrints("not found", channel='stderr'):
417 426 ip.run_cell("%%time\n"
418 427 "run = 0\n"
419 428 "run += 1")
420 429
421 430 def test_multiline_time():
422 431 """Make sure last statement from time return a value."""
423 432 ip = get_ipython()
424 433 ip.user_ns.pop('run', None)
425 434
426 435 ip.run_cell(dedent("""\
427 436 %%time
428 437 a = "ho"
429 438 b = "hey"
430 439 a+b
431 440 """))
432 441 nt.assert_equal(ip.user_ns_hidden['_'], 'hohey')
433 442
434 443 def test_time_local_ns():
435 444 """
436 445 Test that local_ns is actually global_ns when running a cell magic
437 446 """
438 447 ip = get_ipython()
439 448 ip.run_cell("%%time\n"
440 449 "myvar = 1")
441 450 nt.assert_equal(ip.user_ns['myvar'], 1)
442 451 del ip.user_ns['myvar']
443 452
444 453 def test_doctest_mode():
445 454 "Toggle doctest_mode twice, it should be a no-op and run without error"
446 455 _ip.magic('doctest_mode')
447 456 _ip.magic('doctest_mode')
448 457
449 458
450 459 def test_parse_options():
451 460 """Tests for basic options parsing in magics."""
452 461 # These are only the most minimal of tests, more should be added later. At
453 462 # the very least we check that basic text/unicode calls work OK.
454 463 m = DummyMagics(_ip)
455 464 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
456 465 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
457 466
458 467
459 468 def test_dirops():
460 469 """Test various directory handling operations."""
461 470 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
462 471 curpath = os.getcwd
463 472 startdir = os.getcwd()
464 473 ipdir = os.path.realpath(_ip.ipython_dir)
465 474 try:
466 475 _ip.magic('cd "%s"' % ipdir)
467 476 nt.assert_equal(curpath(), ipdir)
468 477 _ip.magic('cd -')
469 478 nt.assert_equal(curpath(), startdir)
470 479 _ip.magic('pushd "%s"' % ipdir)
471 480 nt.assert_equal(curpath(), ipdir)
472 481 _ip.magic('popd')
473 482 nt.assert_equal(curpath(), startdir)
474 483 finally:
475 484 os.chdir(startdir)
476 485
477 486
478 487 def test_cd_force_quiet():
479 488 """Test OSMagics.cd_force_quiet option"""
480 489 _ip.config.OSMagics.cd_force_quiet = True
481 490 osmagics = osm.OSMagics(shell=_ip)
482 491
483 492 startdir = os.getcwd()
484 493 ipdir = os.path.realpath(_ip.ipython_dir)
485 494
486 495 try:
487 496 with tt.AssertNotPrints(ipdir):
488 497 osmagics.cd('"%s"' % ipdir)
489 498 with tt.AssertNotPrints(startdir):
490 499 osmagics.cd('-')
491 500 finally:
492 501 os.chdir(startdir)
493 502
494 503
495 504 def test_xmode():
496 505 # Calling xmode three times should be a no-op
497 506 xmode = _ip.InteractiveTB.mode
498 507 for i in range(4):
499 508 _ip.magic("xmode")
500 509 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
501 510
502 511 def test_reset_hard():
503 512 monitor = []
504 513 class A(object):
505 514 def __del__(self):
506 515 monitor.append(1)
507 516 def __repr__(self):
508 517 return "<A instance>"
509 518
510 519 _ip.user_ns["a"] = A()
511 520 _ip.run_cell("a")
512 521
513 522 nt.assert_equal(monitor, [])
514 523 _ip.magic("reset -f")
515 524 nt.assert_equal(monitor, [1])
516 525
517 526 class TestXdel(tt.TempFileMixin):
518 527 def test_xdel(self):
519 528 """Test that references from %run are cleared by xdel."""
520 529 src = ("class A(object):\n"
521 530 " monitor = []\n"
522 531 " def __del__(self):\n"
523 532 " self.monitor.append(1)\n"
524 533 "a = A()\n")
525 534 self.mktmp(src)
526 535 # %run creates some hidden references...
527 536 _ip.magic("run %s" % self.fname)
528 537 # ... as does the displayhook.
529 538 _ip.run_cell("a")
530 539
531 540 monitor = _ip.user_ns["A"].monitor
532 541 nt.assert_equal(monitor, [])
533 542
534 543 _ip.magic("xdel a")
535 544
536 545 # Check that a's __del__ method has been called.
537 546 nt.assert_equal(monitor, [1])
538 547
539 548 def doctest_who():
540 549 """doctest for %who
541 550
542 551 In [1]: %reset -f
543 552
544 553 In [2]: alpha = 123
545 554
546 555 In [3]: beta = 'beta'
547 556
548 557 In [4]: %who int
549 558 alpha
550 559
551 560 In [5]: %who str
552 561 beta
553 562
554 563 In [6]: %whos
555 564 Variable Type Data/Info
556 565 ----------------------------
557 566 alpha int 123
558 567 beta str beta
559 568
560 569 In [7]: %who_ls
561 570 Out[7]: ['alpha', 'beta']
562 571 """
563 572
564 573 def test_whos():
565 574 """Check that whos is protected against objects where repr() fails."""
566 575 class A(object):
567 576 def __repr__(self):
568 577 raise Exception()
569 578 _ip.user_ns['a'] = A()
570 579 _ip.magic("whos")
571 580
572 581 def doctest_precision():
573 582 """doctest for %precision
574 583
575 584 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
576 585
577 586 In [2]: %precision 5
578 587 Out[2]: '%.5f'
579 588
580 589 In [3]: f.float_format
581 590 Out[3]: '%.5f'
582 591
583 592 In [4]: %precision %e
584 593 Out[4]: '%e'
585 594
586 595 In [5]: f(3.1415927)
587 596 Out[5]: '3.141593e+00'
588 597 """
589 598
590 599 def test_psearch():
591 600 with tt.AssertPrints("dict.fromkeys"):
592 601 _ip.run_cell("dict.fr*?")
593 602
594 603 def test_timeit_shlex():
595 604 """test shlex issues with timeit (#1109)"""
596 605 _ip.ex("def f(*a,**kw): pass")
597 606 _ip.magic('timeit -n1 "this is a bug".count(" ")')
598 607 _ip.magic('timeit -r1 -n1 f(" ", 1)')
599 608 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
600 609 _ip.magic('timeit -r1 -n1 ("a " + "b")')
601 610 _ip.magic('timeit -r1 -n1 f("a " + "b")')
602 611 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
603 612
604 613
605 614 def test_timeit_special_syntax():
606 615 "Test %%timeit with IPython special syntax"
607 616 @register_line_magic
608 617 def lmagic(line):
609 618 ip = get_ipython()
610 619 ip.user_ns['lmagic_out'] = line
611 620
612 621 # line mode test
613 622 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
614 623 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
615 624 # cell mode test
616 625 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
617 626 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
618 627
619 628 def test_timeit_return():
620 629 """
621 630 test whether timeit -o return object
622 631 """
623 632
624 633 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
625 634 assert(res is not None)
626 635
627 636 def test_timeit_quiet():
628 637 """
629 638 test quiet option of timeit magic
630 639 """
631 640 with tt.AssertNotPrints("loops"):
632 641 _ip.run_cell("%timeit -n1 -r1 -q 1")
633 642
634 643 def test_timeit_return_quiet():
635 644 with tt.AssertNotPrints("loops"):
636 645 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
637 646 assert (res is not None)
638 647
639 648 def test_timeit_invalid_return():
640 649 with nt.assert_raises_regex(SyntaxError, "outside function"):
641 650 _ip.run_line_magic('timeit', 'return')
642 651
643 652 @dec.skipif(execution.profile is None)
644 653 def test_prun_special_syntax():
645 654 "Test %%prun with IPython special syntax"
646 655 @register_line_magic
647 656 def lmagic(line):
648 657 ip = get_ipython()
649 658 ip.user_ns['lmagic_out'] = line
650 659
651 660 # line mode test
652 661 _ip.run_line_magic('prun', '-q %lmagic my line')
653 662 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
654 663 # cell mode test
655 664 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
656 665 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
657 666
658 667 @dec.skipif(execution.profile is None)
659 668 def test_prun_quotes():
660 669 "Test that prun does not clobber string escapes (GH #1302)"
661 670 _ip.magic(r"prun -q x = '\t'")
662 671 nt.assert_equal(_ip.user_ns['x'], '\t')
663 672
664 673 def test_extension():
665 674 # Debugging information for failures of this test
666 675 print('sys.path:')
667 676 for p in sys.path:
668 677 print(' ', p)
669 678 print('CWD', os.getcwd())
670 679
671 680 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
672 681 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
673 682 sys.path.insert(0, daft_path)
674 683 try:
675 684 _ip.user_ns.pop('arq', None)
676 685 invalidate_caches() # Clear import caches
677 686 _ip.magic("load_ext daft_extension")
678 687 nt.assert_equal(_ip.user_ns['arq'], 185)
679 688 _ip.magic("unload_ext daft_extension")
680 689 assert 'arq' not in _ip.user_ns
681 690 finally:
682 691 sys.path.remove(daft_path)
683 692
684 693
685 694 def test_notebook_export_json():
686 695 _ip = get_ipython()
687 696 _ip.history_manager.reset() # Clear any existing history.
688 697 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
689 698 for i, cmd in enumerate(cmds, start=1):
690 699 _ip.history_manager.store_inputs(i, cmd)
691 700 with TemporaryDirectory() as td:
692 701 outfile = os.path.join(td, "nb.ipynb")
693 702 _ip.magic("notebook -e %s" % outfile)
694 703
695 704
696 705 class TestEnv(TestCase):
697 706
698 707 def test_env(self):
699 708 env = _ip.magic("env")
700 709 self.assertTrue(isinstance(env, dict))
701 710
702 711 def test_env_get_set_simple(self):
703 712 env = _ip.magic("env var val1")
704 713 self.assertEqual(env, None)
705 714 self.assertEqual(os.environ['var'], 'val1')
706 715 self.assertEqual(_ip.magic("env var"), 'val1')
707 716 env = _ip.magic("env var=val2")
708 717 self.assertEqual(env, None)
709 718 self.assertEqual(os.environ['var'], 'val2')
710 719
711 720 def test_env_get_set_complex(self):
712 721 env = _ip.magic("env var 'val1 '' 'val2")
713 722 self.assertEqual(env, None)
714 723 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
715 724 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
716 725 env = _ip.magic('env var=val2 val3="val4')
717 726 self.assertEqual(env, None)
718 727 self.assertEqual(os.environ['var'], 'val2 val3="val4')
719 728
720 729 def test_env_set_bad_input(self):
721 730 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
722 731
723 732 def test_env_set_whitespace(self):
724 733 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
725 734
726 735
727 736 class CellMagicTestCase(TestCase):
728 737
729 738 def check_ident(self, magic):
730 739 # Manually called, we get the result
731 740 out = _ip.run_cell_magic(magic, 'a', 'b')
732 741 nt.assert_equal(out, ('a','b'))
733 742 # Via run_cell, it goes into the user's namespace via displayhook
734 743 _ip.run_cell('%%' + magic +' c\nd\n')
735 744 nt.assert_equal(_ip.user_ns['_'], ('c','d\n'))
736 745
737 746 def test_cell_magic_func_deco(self):
738 747 "Cell magic using simple decorator"
739 748 @register_cell_magic
740 749 def cellm(line, cell):
741 750 return line, cell
742 751
743 752 self.check_ident('cellm')
744 753
745 754 def test_cell_magic_reg(self):
746 755 "Cell magic manually registered"
747 756 def cellm(line, cell):
748 757 return line, cell
749 758
750 759 _ip.register_magic_function(cellm, 'cell', 'cellm2')
751 760 self.check_ident('cellm2')
752 761
753 762 def test_cell_magic_class(self):
754 763 "Cell magics declared via a class"
755 764 @magics_class
756 765 class MyMagics(Magics):
757 766
758 767 @cell_magic
759 768 def cellm3(self, line, cell):
760 769 return line, cell
761 770
762 771 _ip.register_magics(MyMagics)
763 772 self.check_ident('cellm3')
764 773
765 774 def test_cell_magic_class2(self):
766 775 "Cell magics declared via a class, #2"
767 776 @magics_class
768 777 class MyMagics2(Magics):
769 778
770 779 @cell_magic('cellm4')
771 780 def cellm33(self, line, cell):
772 781 return line, cell
773 782
774 783 _ip.register_magics(MyMagics2)
775 784 self.check_ident('cellm4')
776 785 # Check that nothing is registered as 'cellm33'
777 786 c33 = _ip.find_cell_magic('cellm33')
778 787 nt.assert_equal(c33, None)
779 788
780 789 def test_file():
781 790 """Basic %%writefile"""
782 791 ip = get_ipython()
783 792 with TemporaryDirectory() as td:
784 793 fname = os.path.join(td, 'file1')
785 794 ip.run_cell_magic("writefile", fname, u'\n'.join([
786 795 'line1',
787 796 'line2',
788 797 ]))
789 798 with open(fname) as f:
790 799 s = f.read()
791 800 nt.assert_in('line1\n', s)
792 801 nt.assert_in('line2', s)
793 802
794 803 @dec.skip_win32
795 804 def test_file_single_quote():
796 805 """Basic %%writefile with embedded single quotes"""
797 806 ip = get_ipython()
798 807 with TemporaryDirectory() as td:
799 808 fname = os.path.join(td, '\'file1\'')
800 809 ip.run_cell_magic("writefile", fname, u'\n'.join([
801 810 'line1',
802 811 'line2',
803 812 ]))
804 813 with open(fname) as f:
805 814 s = f.read()
806 815 nt.assert_in('line1\n', s)
807 816 nt.assert_in('line2', s)
808 817
809 818 @dec.skip_win32
810 819 def test_file_double_quote():
811 820 """Basic %%writefile with embedded double quotes"""
812 821 ip = get_ipython()
813 822 with TemporaryDirectory() as td:
814 823 fname = os.path.join(td, '"file1"')
815 824 ip.run_cell_magic("writefile", fname, u'\n'.join([
816 825 'line1',
817 826 'line2',
818 827 ]))
819 828 with open(fname) as f:
820 829 s = f.read()
821 830 nt.assert_in('line1\n', s)
822 831 nt.assert_in('line2', s)
823 832
824 833 def test_file_var_expand():
825 834 """%%writefile $filename"""
826 835 ip = get_ipython()
827 836 with TemporaryDirectory() as td:
828 837 fname = os.path.join(td, 'file1')
829 838 ip.user_ns['filename'] = fname
830 839 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
831 840 'line1',
832 841 'line2',
833 842 ]))
834 843 with open(fname) as f:
835 844 s = f.read()
836 845 nt.assert_in('line1\n', s)
837 846 nt.assert_in('line2', s)
838 847
839 848 def test_file_unicode():
840 849 """%%writefile with unicode cell"""
841 850 ip = get_ipython()
842 851 with TemporaryDirectory() as td:
843 852 fname = os.path.join(td, 'file1')
844 853 ip.run_cell_magic("writefile", fname, u'\n'.join([
845 854 u'linΓ©1',
846 855 u'linΓ©2',
847 856 ]))
848 857 with io.open(fname, encoding='utf-8') as f:
849 858 s = f.read()
850 859 nt.assert_in(u'linΓ©1\n', s)
851 860 nt.assert_in(u'linΓ©2', s)
852 861
853 862 def test_file_amend():
854 863 """%%writefile -a amends files"""
855 864 ip = get_ipython()
856 865 with TemporaryDirectory() as td:
857 866 fname = os.path.join(td, 'file2')
858 867 ip.run_cell_magic("writefile", fname, u'\n'.join([
859 868 'line1',
860 869 'line2',
861 870 ]))
862 871 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
863 872 'line3',
864 873 'line4',
865 874 ]))
866 875 with open(fname) as f:
867 876 s = f.read()
868 877 nt.assert_in('line1\n', s)
869 878 nt.assert_in('line3\n', s)
870 879
871 880 def test_file_spaces():
872 881 """%%file with spaces in filename"""
873 882 ip = get_ipython()
874 883 with TemporaryWorkingDirectory() as td:
875 884 fname = "file name"
876 885 ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([
877 886 'line1',
878 887 'line2',
879 888 ]))
880 889 with open(fname) as f:
881 890 s = f.read()
882 891 nt.assert_in('line1\n', s)
883 892 nt.assert_in('line2', s)
884 893
885 894 def test_script_config():
886 895 ip = get_ipython()
887 896 ip.config.ScriptMagics.script_magics = ['whoda']
888 897 sm = script.ScriptMagics(shell=ip)
889 898 nt.assert_in('whoda', sm.magics['cell'])
890 899
891 900 @dec.skip_win32
892 901 def test_script_out():
893 902 ip = get_ipython()
894 903 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
895 904 nt.assert_equal(ip.user_ns['output'], 'hi\n')
896 905
897 906 @dec.skip_win32
898 907 def test_script_err():
899 908 ip = get_ipython()
900 909 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
901 910 nt.assert_equal(ip.user_ns['error'], 'hello\n')
902 911
903 912 @dec.skip_win32
904 913 def test_script_out_err():
905 914 ip = get_ipython()
906 915 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
907 916 nt.assert_equal(ip.user_ns['output'], 'hi\n')
908 917 nt.assert_equal(ip.user_ns['error'], 'hello\n')
909 918
910 919 @dec.skip_win32
911 920 def test_script_bg_out():
912 921 ip = get_ipython()
913 922 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
914 923
915 924 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
916 925 ip.user_ns['output'].close()
917 926
918 927 @dec.skip_win32
919 928 def test_script_bg_err():
920 929 ip = get_ipython()
921 930 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
922 931 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
923 932 ip.user_ns['error'].close()
924 933
925 934 @dec.skip_win32
926 935 def test_script_bg_out_err():
927 936 ip = get_ipython()
928 937 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
929 938 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
930 939 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
931 940 ip.user_ns['output'].close()
932 941 ip.user_ns['error'].close()
933 942
934 943 def test_script_defaults():
935 944 ip = get_ipython()
936 945 for cmd in ['sh', 'bash', 'perl', 'ruby']:
937 946 try:
938 947 find_cmd(cmd)
939 948 except Exception:
940 949 pass
941 950 else:
942 951 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
943 952
944 953
945 954 @magics_class
946 955 class FooFoo(Magics):
947 956 """class with both %foo and %%foo magics"""
948 957 @line_magic('foo')
949 958 def line_foo(self, line):
950 959 "I am line foo"
951 960 pass
952 961
953 962 @cell_magic("foo")
954 963 def cell_foo(self, line, cell):
955 964 "I am cell foo, not line foo"
956 965 pass
957 966
958 967 def test_line_cell_info():
959 968 """%%foo and %foo magics are distinguishable to inspect"""
960 969 ip = get_ipython()
961 970 ip.magics_manager.register(FooFoo)
962 971 oinfo = ip.object_inspect('foo')
963 972 nt.assert_true(oinfo['found'])
964 973 nt.assert_true(oinfo['ismagic'])
965 974
966 975 oinfo = ip.object_inspect('%%foo')
967 976 nt.assert_true(oinfo['found'])
968 977 nt.assert_true(oinfo['ismagic'])
969 978 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
970 979
971 980 oinfo = ip.object_inspect('%foo')
972 981 nt.assert_true(oinfo['found'])
973 982 nt.assert_true(oinfo['ismagic'])
974 983 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
975 984
976 985 def test_multiple_magics():
977 986 ip = get_ipython()
978 987 foo1 = FooFoo(ip)
979 988 foo2 = FooFoo(ip)
980 989 mm = ip.magics_manager
981 990 mm.register(foo1)
982 991 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
983 992 mm.register(foo2)
984 993 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
985 994
986 995 def test_alias_magic():
987 996 """Test %alias_magic."""
988 997 ip = get_ipython()
989 998 mm = ip.magics_manager
990 999
991 1000 # Basic operation: both cell and line magics are created, if possible.
992 1001 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
993 1002 nt.assert_in('timeit_alias', mm.magics['line'])
994 1003 nt.assert_in('timeit_alias', mm.magics['cell'])
995 1004
996 1005 # --cell is specified, line magic not created.
997 1006 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
998 1007 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
999 1008 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
1000 1009
1001 1010 # Test that line alias is created successfully.
1002 1011 ip.run_line_magic('alias_magic', '--line env_alias env')
1003 1012 nt.assert_equal(ip.run_line_magic('env', ''),
1004 1013 ip.run_line_magic('env_alias', ''))
1005 1014
1006 1015 # Test that line alias with parameters passed in is created successfully.
1007 1016 ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3'))
1008 1017 nt.assert_in('history_alias', mm.magics['line'])
1009 1018
1010 1019
1011 1020 def test_save():
1012 1021 """Test %save."""
1013 1022 ip = get_ipython()
1014 1023 ip.history_manager.reset() # Clear any existing history.
1015 1024 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
1016 1025 for i, cmd in enumerate(cmds, start=1):
1017 1026 ip.history_manager.store_inputs(i, cmd)
1018 1027 with TemporaryDirectory() as tmpdir:
1019 1028 file = os.path.join(tmpdir, "testsave.py")
1020 1029 ip.run_line_magic("save", "%s 1-10" % file)
1021 1030 with open(file) as f:
1022 1031 content = f.read()
1023 1032 nt.assert_equal(content.count(cmds[0]), 1)
1024 1033 nt.assert_in('coding: utf-8', content)
1025 1034 ip.run_line_magic("save", "-a %s 1-10" % file)
1026 1035 with open(file) as f:
1027 1036 content = f.read()
1028 1037 nt.assert_equal(content.count(cmds[0]), 2)
1029 1038 nt.assert_in('coding: utf-8', content)
1030 1039
1031 1040
1032 1041 def test_store():
1033 1042 """Test %store."""
1034 1043 ip = get_ipython()
1035 1044 ip.run_line_magic('load_ext', 'storemagic')
1036 1045
1037 1046 # make sure the storage is empty
1038 1047 ip.run_line_magic('store', '-z')
1039 1048 ip.user_ns['var'] = 42
1040 1049 ip.run_line_magic('store', 'var')
1041 1050 ip.user_ns['var'] = 39
1042 1051 ip.run_line_magic('store', '-r')
1043 1052 nt.assert_equal(ip.user_ns['var'], 42)
1044 1053
1045 1054 ip.run_line_magic('store', '-d var')
1046 1055 ip.user_ns['var'] = 39
1047 1056 ip.run_line_magic('store' , '-r')
1048 1057 nt.assert_equal(ip.user_ns['var'], 39)
1049 1058
1050 1059
1051 1060 def _run_edit_test(arg_s, exp_filename=None,
1052 1061 exp_lineno=-1,
1053 1062 exp_contents=None,
1054 1063 exp_is_temp=None):
1055 1064 ip = get_ipython()
1056 1065 M = code.CodeMagics(ip)
1057 1066 last_call = ['','']
1058 1067 opts,args = M.parse_options(arg_s,'prxn:')
1059 1068 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1060 1069
1061 1070 if exp_filename is not None:
1062 1071 nt.assert_equal(exp_filename, filename)
1063 1072 if exp_contents is not None:
1064 1073 with io.open(filename, 'r', encoding='utf-8') as f:
1065 1074 contents = f.read()
1066 1075 nt.assert_equal(exp_contents, contents)
1067 1076 if exp_lineno != -1:
1068 1077 nt.assert_equal(exp_lineno, lineno)
1069 1078 if exp_is_temp is not None:
1070 1079 nt.assert_equal(exp_is_temp, is_temp)
1071 1080
1072 1081
1073 1082 def test_edit_interactive():
1074 1083 """%edit on interactively defined objects"""
1075 1084 ip = get_ipython()
1076 1085 n = ip.execution_count
1077 1086 ip.run_cell(u"def foo(): return 1", store_history=True)
1078 1087
1079 1088 try:
1080 1089 _run_edit_test("foo")
1081 1090 except code.InteractivelyDefined as e:
1082 1091 nt.assert_equal(e.index, n)
1083 1092 else:
1084 1093 raise AssertionError("Should have raised InteractivelyDefined")
1085 1094
1086 1095
1087 1096 def test_edit_cell():
1088 1097 """%edit [cell id]"""
1089 1098 ip = get_ipython()
1090 1099
1091 1100 ip.run_cell(u"def foo(): return 1", store_history=True)
1092 1101
1093 1102 # test
1094 1103 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1095 1104
1096 1105 def test_bookmark():
1097 1106 ip = get_ipython()
1098 1107 ip.run_line_magic('bookmark', 'bmname')
1099 1108 with tt.AssertPrints('bmname'):
1100 1109 ip.run_line_magic('bookmark', '-l')
1101 1110 ip.run_line_magic('bookmark', '-d bmname')
1102 1111
1103 1112 def test_ls_magic():
1104 1113 ip = get_ipython()
1105 1114 json_formatter = ip.display_formatter.formatters['application/json']
1106 1115 json_formatter.enabled = True
1107 1116 lsmagic = ip.magic('lsmagic')
1108 1117 with warnings.catch_warnings(record=True) as w:
1109 1118 j = json_formatter(lsmagic)
1110 1119 nt.assert_equal(sorted(j), ['cell', 'line'])
1111 1120 nt.assert_equal(w, []) # no warnings
1112 1121
1113 1122 def test_strip_initial_indent():
1114 1123 def sii(s):
1115 1124 lines = s.splitlines()
1116 1125 return '\n'.join(code.strip_initial_indent(lines))
1117 1126
1118 1127 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
1119 1128 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
1120 1129 nt.assert_equal(sii("a\n b"), "a\n b")
1121 1130
1122 1131 def test_logging_magic_quiet_from_arg():
1123 1132 _ip.config.LoggingMagics.quiet = False
1124 1133 lm = logging.LoggingMagics(shell=_ip)
1125 1134 with TemporaryDirectory() as td:
1126 1135 try:
1127 1136 with tt.AssertNotPrints(re.compile("Activating.*")):
1128 1137 lm.logstart('-q {}'.format(
1129 1138 os.path.join(td, "quiet_from_arg.log")))
1130 1139 finally:
1131 1140 _ip.logger.logstop()
1132 1141
1133 1142 def test_logging_magic_quiet_from_config():
1134 1143 _ip.config.LoggingMagics.quiet = True
1135 1144 lm = logging.LoggingMagics(shell=_ip)
1136 1145 with TemporaryDirectory() as td:
1137 1146 try:
1138 1147 with tt.AssertNotPrints(re.compile("Activating.*")):
1139 1148 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1140 1149 finally:
1141 1150 _ip.logger.logstop()
1142 1151
1143 1152
1144 1153 def test_logging_magic_not_quiet():
1145 1154 _ip.config.LoggingMagics.quiet = False
1146 1155 lm = logging.LoggingMagics(shell=_ip)
1147 1156 with TemporaryDirectory() as td:
1148 1157 try:
1149 1158 with tt.AssertPrints(re.compile("Activating.*")):
1150 1159 lm.logstart(os.path.join(td, "not_quiet.log"))
1151 1160 finally:
1152 1161 _ip.logger.logstop()
1153 1162
1154 1163
1155 1164 def test_time_no_var_expand():
1156 1165 _ip.user_ns['a'] = 5
1157 1166 _ip.user_ns['b'] = []
1158 1167 _ip.magic('time b.append("{a}")')
1159 1168 assert _ip.user_ns['b'] == ['{a}']
1160 1169
1161 1170
1162 1171 # this is slow, put at the end for local testing.
1163 1172 def test_timeit_arguments():
1164 1173 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1165 1174 if sys.version_info < (3,7):
1166 1175 _ip.magic("timeit -n1 -r1 ('#')")
1167 1176 else:
1168 1177 # 3.7 optimize no-op statement like above out, and complain there is
1169 1178 # nothing in the for loop.
1170 1179 _ip.magic("timeit -n1 -r1 a=('#')")
General Comments 0
You need to be logged in to leave comments. Login now