##// END OF EJS Templates
change magics from %%file to %%writefile
Shao Yang -
Show More
@@ -1,1080 +1,1080
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 unittest import TestCase
13 13 from importlib import invalidate_caches
14 14 from io import StringIO
15 15
16 16 import nose.tools as nt
17 17
18 18 import shlex
19 19
20 20 from IPython import get_ipython
21 21 from IPython.core import magic
22 22 from IPython.core.error import UsageError
23 23 from IPython.core.magic import (Magics, magics_class, line_magic,
24 24 cell_magic,
25 25 register_line_magic, register_cell_magic)
26 26 from IPython.core.magics import execution, script, code, logging
27 27 from IPython.testing import decorators as dec
28 28 from IPython.testing import tools as tt
29 29 from IPython.utils.io import capture_output
30 30 from IPython.utils.tempdir import TemporaryDirectory
31 31 from IPython.utils.process import find_cmd
32 32
33 33
34 34
35 35 _ip = get_ipython()
36 36
37 37 @magic.magics_class
38 38 class DummyMagics(magic.Magics): pass
39 39
40 40 def test_extract_code_ranges():
41 41 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
42 42 expected = [(0, 1),
43 43 (2, 3),
44 44 (4, 6),
45 45 (6, 9),
46 46 (9, 14),
47 47 (16, None),
48 48 (None, 9),
49 49 (9, None),
50 50 (None, 13),
51 51 (None, None)]
52 52 actual = list(code.extract_code_ranges(instr))
53 53 nt.assert_equal(actual, expected)
54 54
55 55 def test_extract_symbols():
56 56 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
57 57 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
58 58 expected = [([], ['a']),
59 59 (["def b():\n return 42\n"], []),
60 60 (["class A: pass\n"], []),
61 61 (["class A: pass\n", "def b():\n return 42\n"], []),
62 62 (["class A: pass\n"], ['a']),
63 63 ([], ['z'])]
64 64 for symbols, exp in zip(symbols_args, expected):
65 65 nt.assert_equal(code.extract_symbols(source, symbols), exp)
66 66
67 67
68 68 def test_extract_symbols_raises_exception_with_non_python_code():
69 69 source = ("=begin A Ruby program :)=end\n"
70 70 "def hello\n"
71 71 "puts 'Hello world'\n"
72 72 "end")
73 73 with nt.assert_raises(SyntaxError):
74 74 code.extract_symbols(source, "hello")
75 75
76 76
77 77 def test_magic_not_found():
78 78 # magic not found raises UsageError
79 79 with nt.assert_raises(UsageError):
80 80 _ip.magic('doesntexist')
81 81
82 82 # ensure result isn't success when a magic isn't found
83 83 result = _ip.run_cell('%doesntexist')
84 84 assert isinstance(result.error_in_exec, UsageError)
85 85
86 86
87 87 def test_cell_magic_not_found():
88 88 # magic not found raises UsageError
89 89 with nt.assert_raises(UsageError):
90 90 _ip.run_cell_magic('doesntexist', 'line', 'cell')
91 91
92 92 # ensure result isn't success when a magic isn't found
93 93 result = _ip.run_cell('%%doesntexist')
94 94 assert isinstance(result.error_in_exec, UsageError)
95 95
96 96
97 97 def test_magic_error_status():
98 98 def fail(shell):
99 99 1/0
100 100 _ip.register_magic_function(fail)
101 101 result = _ip.run_cell('%fail')
102 102 assert isinstance(result.error_in_exec, ZeroDivisionError)
103 103
104 104
105 105 def test_config():
106 106 """ test that config magic does not raise
107 107 can happen if Configurable init is moved too early into
108 108 Magics.__init__ as then a Config object will be registered as a
109 109 magic.
110 110 """
111 111 ## should not raise.
112 112 _ip.magic('config')
113 113
114 114 def test_config_available_configs():
115 115 """ test that config magic prints available configs in unique and
116 116 sorted order. """
117 117 with capture_output() as captured:
118 118 _ip.magic('config')
119 119
120 120 stdout = captured.stdout
121 121 config_classes = stdout.strip().split('\n')[1:]
122 122 nt.assert_list_equal(config_classes, sorted(set(config_classes)))
123 123
124 124 def test_config_print_class():
125 125 """ test that config with a classname prints the class's options. """
126 126 with capture_output() as captured:
127 127 _ip.magic('config TerminalInteractiveShell')
128 128
129 129 stdout = captured.stdout
130 130 if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]):
131 131 print(stdout)
132 132 raise AssertionError("1st line of stdout not like "
133 133 "'TerminalInteractiveShell.* options'")
134 134
135 135 def test_rehashx():
136 136 # clear up everything
137 137 _ip.alias_manager.clear_aliases()
138 138 del _ip.db['syscmdlist']
139 139
140 140 _ip.magic('rehashx')
141 141 # Practically ALL ipython development systems will have more than 10 aliases
142 142
143 143 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
144 144 for name, cmd in _ip.alias_manager.aliases:
145 145 # we must strip dots from alias names
146 146 nt.assert_not_in('.', name)
147 147
148 148 # rehashx must fill up syscmdlist
149 149 scoms = _ip.db['syscmdlist']
150 150 nt.assert_true(len(scoms) > 10)
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 403
404 404 @dec.skip_win32
405 405 def test_time2():
406 406 ip = get_ipython()
407 407
408 408 with tt.AssertPrints("CPU times: user "):
409 409 ip.run_cell("%time None")
410 410
411 411 def test_time3():
412 412 """Erroneous magic function calls, issue gh-3334"""
413 413 ip = get_ipython()
414 414 ip.user_ns.pop('run', None)
415 415
416 416 with tt.AssertNotPrints("not found", channel='stderr'):
417 417 ip.run_cell("%%time\n"
418 418 "run = 0\n"
419 419 "run += 1")
420 420
421 421 def test_doctest_mode():
422 422 "Toggle doctest_mode twice, it should be a no-op and run without error"
423 423 _ip.magic('doctest_mode')
424 424 _ip.magic('doctest_mode')
425 425
426 426
427 427 def test_parse_options():
428 428 """Tests for basic options parsing in magics."""
429 429 # These are only the most minimal of tests, more should be added later. At
430 430 # the very least we check that basic text/unicode calls work OK.
431 431 m = DummyMagics(_ip)
432 432 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
433 433 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
434 434
435 435
436 436 def test_dirops():
437 437 """Test various directory handling operations."""
438 438 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
439 439 curpath = os.getcwd
440 440 startdir = os.getcwd()
441 441 ipdir = os.path.realpath(_ip.ipython_dir)
442 442 try:
443 443 _ip.magic('cd "%s"' % ipdir)
444 444 nt.assert_equal(curpath(), ipdir)
445 445 _ip.magic('cd -')
446 446 nt.assert_equal(curpath(), startdir)
447 447 _ip.magic('pushd "%s"' % ipdir)
448 448 nt.assert_equal(curpath(), ipdir)
449 449 _ip.magic('popd')
450 450 nt.assert_equal(curpath(), startdir)
451 451 finally:
452 452 os.chdir(startdir)
453 453
454 454
455 455 def test_xmode():
456 456 # Calling xmode three times should be a no-op
457 457 xmode = _ip.InteractiveTB.mode
458 458 for i in range(3):
459 459 _ip.magic("xmode")
460 460 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
461 461
462 462 def test_reset_hard():
463 463 monitor = []
464 464 class A(object):
465 465 def __del__(self):
466 466 monitor.append(1)
467 467 def __repr__(self):
468 468 return "<A instance>"
469 469
470 470 _ip.user_ns["a"] = A()
471 471 _ip.run_cell("a")
472 472
473 473 nt.assert_equal(monitor, [])
474 474 _ip.magic("reset -f")
475 475 nt.assert_equal(monitor, [1])
476 476
477 477 class TestXdel(tt.TempFileMixin):
478 478 def test_xdel(self):
479 479 """Test that references from %run are cleared by xdel."""
480 480 src = ("class A(object):\n"
481 481 " monitor = []\n"
482 482 " def __del__(self):\n"
483 483 " self.monitor.append(1)\n"
484 484 "a = A()\n")
485 485 self.mktmp(src)
486 486 # %run creates some hidden references...
487 487 _ip.magic("run %s" % self.fname)
488 488 # ... as does the displayhook.
489 489 _ip.run_cell("a")
490 490
491 491 monitor = _ip.user_ns["A"].monitor
492 492 nt.assert_equal(monitor, [])
493 493
494 494 _ip.magic("xdel a")
495 495
496 496 # Check that a's __del__ method has been called.
497 497 nt.assert_equal(monitor, [1])
498 498
499 499 def doctest_who():
500 500 """doctest for %who
501 501
502 502 In [1]: %reset -f
503 503
504 504 In [2]: alpha = 123
505 505
506 506 In [3]: beta = 'beta'
507 507
508 508 In [4]: %who int
509 509 alpha
510 510
511 511 In [5]: %who str
512 512 beta
513 513
514 514 In [6]: %whos
515 515 Variable Type Data/Info
516 516 ----------------------------
517 517 alpha int 123
518 518 beta str beta
519 519
520 520 In [7]: %who_ls
521 521 Out[7]: ['alpha', 'beta']
522 522 """
523 523
524 524 def test_whos():
525 525 """Check that whos is protected against objects where repr() fails."""
526 526 class A(object):
527 527 def __repr__(self):
528 528 raise Exception()
529 529 _ip.user_ns['a'] = A()
530 530 _ip.magic("whos")
531 531
532 532 def doctest_precision():
533 533 """doctest for %precision
534 534
535 535 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
536 536
537 537 In [2]: %precision 5
538 538 Out[2]: '%.5f'
539 539
540 540 In [3]: f.float_format
541 541 Out[3]: '%.5f'
542 542
543 543 In [4]: %precision %e
544 544 Out[4]: '%e'
545 545
546 546 In [5]: f(3.1415927)
547 547 Out[5]: '3.141593e+00'
548 548 """
549 549
550 550 def test_psearch():
551 551 with tt.AssertPrints("dict.fromkeys"):
552 552 _ip.run_cell("dict.fr*?")
553 553
554 554 def test_timeit_shlex():
555 555 """test shlex issues with timeit (#1109)"""
556 556 _ip.ex("def f(*a,**kw): pass")
557 557 _ip.magic('timeit -n1 "this is a bug".count(" ")')
558 558 _ip.magic('timeit -r1 -n1 f(" ", 1)')
559 559 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
560 560 _ip.magic('timeit -r1 -n1 ("a " + "b")')
561 561 _ip.magic('timeit -r1 -n1 f("a " + "b")')
562 562 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
563 563
564 564
565 565 def test_timeit_special_syntax():
566 566 "Test %%timeit with IPython special syntax"
567 567 @register_line_magic
568 568 def lmagic(line):
569 569 ip = get_ipython()
570 570 ip.user_ns['lmagic_out'] = line
571 571
572 572 # line mode test
573 573 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
574 574 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
575 575 # cell mode test
576 576 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
577 577 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
578 578
579 579 def test_timeit_return():
580 580 """
581 581 test whether timeit -o return object
582 582 """
583 583
584 584 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
585 585 assert(res is not None)
586 586
587 587 def test_timeit_quiet():
588 588 """
589 589 test quiet option of timeit magic
590 590 """
591 591 with tt.AssertNotPrints("loops"):
592 592 _ip.run_cell("%timeit -n1 -r1 -q 1")
593 593
594 594 def test_timeit_return_quiet():
595 595 with tt.AssertNotPrints("loops"):
596 596 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
597 597 assert (res is not None)
598 598
599 599 def test_timeit_invalid_return():
600 600 with nt.assert_raises_regex(SyntaxError, "outside function"):
601 601 _ip.run_line_magic('timeit', 'return')
602 602
603 603 @dec.skipif(execution.profile is None)
604 604 def test_prun_special_syntax():
605 605 "Test %%prun with IPython special syntax"
606 606 @register_line_magic
607 607 def lmagic(line):
608 608 ip = get_ipython()
609 609 ip.user_ns['lmagic_out'] = line
610 610
611 611 # line mode test
612 612 _ip.run_line_magic('prun', '-q %lmagic my line')
613 613 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
614 614 # cell mode test
615 615 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
616 616 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
617 617
618 618 @dec.skipif(execution.profile is None)
619 619 def test_prun_quotes():
620 620 "Test that prun does not clobber string escapes (GH #1302)"
621 621 _ip.magic(r"prun -q x = '\t'")
622 622 nt.assert_equal(_ip.user_ns['x'], '\t')
623 623
624 624 def test_extension():
625 625 # Debugging information for failures of this test
626 626 print('sys.path:')
627 627 for p in sys.path:
628 628 print(' ', p)
629 629 print('CWD', os.getcwd())
630 630
631 631 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
632 632 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
633 633 sys.path.insert(0, daft_path)
634 634 try:
635 635 _ip.user_ns.pop('arq', None)
636 636 invalidate_caches() # Clear import caches
637 637 _ip.magic("load_ext daft_extension")
638 638 nt.assert_equal(_ip.user_ns['arq'], 185)
639 639 _ip.magic("unload_ext daft_extension")
640 640 assert 'arq' not in _ip.user_ns
641 641 finally:
642 642 sys.path.remove(daft_path)
643 643
644 644
645 645 def test_notebook_export_json():
646 646 _ip = get_ipython()
647 647 _ip.history_manager.reset() # Clear any existing history.
648 648 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
649 649 for i, cmd in enumerate(cmds, start=1):
650 650 _ip.history_manager.store_inputs(i, cmd)
651 651 with TemporaryDirectory() as td:
652 652 outfile = os.path.join(td, "nb.ipynb")
653 653 _ip.magic("notebook -e %s" % outfile)
654 654
655 655
656 656 class TestEnv(TestCase):
657 657
658 658 def test_env(self):
659 659 env = _ip.magic("env")
660 660 self.assertTrue(isinstance(env, dict))
661 661
662 662 def test_env_get_set_simple(self):
663 663 env = _ip.magic("env var val1")
664 664 self.assertEqual(env, None)
665 665 self.assertEqual(os.environ['var'], 'val1')
666 666 self.assertEqual(_ip.magic("env var"), 'val1')
667 667 env = _ip.magic("env var=val2")
668 668 self.assertEqual(env, None)
669 669 self.assertEqual(os.environ['var'], 'val2')
670 670
671 671 def test_env_get_set_complex(self):
672 672 env = _ip.magic("env var 'val1 '' 'val2")
673 673 self.assertEqual(env, None)
674 674 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
675 675 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
676 676 env = _ip.magic('env var=val2 val3="val4')
677 677 self.assertEqual(env, None)
678 678 self.assertEqual(os.environ['var'], 'val2 val3="val4')
679 679
680 680 def test_env_set_bad_input(self):
681 681 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
682 682
683 683 def test_env_set_whitespace(self):
684 684 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
685 685
686 686
687 687 class CellMagicTestCase(TestCase):
688 688
689 689 def check_ident(self, magic):
690 690 # Manually called, we get the result
691 691 out = _ip.run_cell_magic(magic, 'a', 'b')
692 692 nt.assert_equal(out, ('a','b'))
693 693 # Via run_cell, it goes into the user's namespace via displayhook
694 694 _ip.run_cell('%%' + magic +' c\nd\n')
695 695 nt.assert_equal(_ip.user_ns['_'], ('c','d\n'))
696 696
697 697 def test_cell_magic_func_deco(self):
698 698 "Cell magic using simple decorator"
699 699 @register_cell_magic
700 700 def cellm(line, cell):
701 701 return line, cell
702 702
703 703 self.check_ident('cellm')
704 704
705 705 def test_cell_magic_reg(self):
706 706 "Cell magic manually registered"
707 707 def cellm(line, cell):
708 708 return line, cell
709 709
710 710 _ip.register_magic_function(cellm, 'cell', 'cellm2')
711 711 self.check_ident('cellm2')
712 712
713 713 def test_cell_magic_class(self):
714 714 "Cell magics declared via a class"
715 715 @magics_class
716 716 class MyMagics(Magics):
717 717
718 718 @cell_magic
719 719 def cellm3(self, line, cell):
720 720 return line, cell
721 721
722 722 _ip.register_magics(MyMagics)
723 723 self.check_ident('cellm3')
724 724
725 725 def test_cell_magic_class2(self):
726 726 "Cell magics declared via a class, #2"
727 727 @magics_class
728 728 class MyMagics2(Magics):
729 729
730 730 @cell_magic('cellm4')
731 731 def cellm33(self, line, cell):
732 732 return line, cell
733 733
734 734 _ip.register_magics(MyMagics2)
735 735 self.check_ident('cellm4')
736 736 # Check that nothing is registered as 'cellm33'
737 737 c33 = _ip.find_cell_magic('cellm33')
738 738 nt.assert_equal(c33, None)
739 739
740 740 def test_file():
741 """Basic %%file"""
741 """Basic %%writefile"""
742 742 ip = get_ipython()
743 743 with TemporaryDirectory() as td:
744 744 fname = os.path.join(td, 'file1')
745 ip.run_cell_magic("file", fname, u'\n'.join([
745 ip.run_cell_magic("writefile", fname, u'\n'.join([
746 746 'line1',
747 747 'line2',
748 748 ]))
749 749 with open(fname) as f:
750 750 s = f.read()
751 751 nt.assert_in('line1\n', s)
752 752 nt.assert_in('line2', s)
753 753
754 754 def test_file_var_expand():
755 """%%file $filename"""
755 """%%writefile $filename"""
756 756 ip = get_ipython()
757 757 with TemporaryDirectory() as td:
758 758 fname = os.path.join(td, 'file1')
759 759 ip.user_ns['filename'] = fname
760 ip.run_cell_magic("file", '$filename', u'\n'.join([
760 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
761 761 'line1',
762 762 'line2',
763 763 ]))
764 764 with open(fname) as f:
765 765 s = f.read()
766 766 nt.assert_in('line1\n', s)
767 767 nt.assert_in('line2', s)
768 768
769 769 def test_file_unicode():
770 """%%file with unicode cell"""
770 """%%writefile with unicode cell"""
771 771 ip = get_ipython()
772 772 with TemporaryDirectory() as td:
773 773 fname = os.path.join(td, 'file1')
774 ip.run_cell_magic("file", fname, u'\n'.join([
774 ip.run_cell_magic("writefile", fname, u'\n'.join([
775 775 u'linΓ©1',
776 776 u'linΓ©2',
777 777 ]))
778 778 with io.open(fname, encoding='utf-8') as f:
779 779 s = f.read()
780 780 nt.assert_in(u'linΓ©1\n', s)
781 781 nt.assert_in(u'linΓ©2', s)
782 782
783 783 def test_file_amend():
784 """%%file -a amends files"""
784 """%%writefile -a amends files"""
785 785 ip = get_ipython()
786 786 with TemporaryDirectory() as td:
787 787 fname = os.path.join(td, 'file2')
788 ip.run_cell_magic("file", fname, u'\n'.join([
788 ip.run_cell_magic("writefile", fname, u'\n'.join([
789 789 'line1',
790 790 'line2',
791 791 ]))
792 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
792 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
793 793 'line3',
794 794 'line4',
795 795 ]))
796 796 with open(fname) as f:
797 797 s = f.read()
798 798 nt.assert_in('line1\n', s)
799 799 nt.assert_in('line3\n', s)
800 800
801 801
802 802 def test_script_config():
803 803 ip = get_ipython()
804 804 ip.config.ScriptMagics.script_magics = ['whoda']
805 805 sm = script.ScriptMagics(shell=ip)
806 806 nt.assert_in('whoda', sm.magics['cell'])
807 807
808 808 @dec.skip_win32
809 809 def test_script_out():
810 810 ip = get_ipython()
811 811 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
812 812 nt.assert_equal(ip.user_ns['output'], 'hi\n')
813 813
814 814 @dec.skip_win32
815 815 def test_script_err():
816 816 ip = get_ipython()
817 817 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
818 818 nt.assert_equal(ip.user_ns['error'], 'hello\n')
819 819
820 820 @dec.skip_win32
821 821 def test_script_out_err():
822 822 ip = get_ipython()
823 823 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
824 824 nt.assert_equal(ip.user_ns['output'], 'hi\n')
825 825 nt.assert_equal(ip.user_ns['error'], 'hello\n')
826 826
827 827 @dec.skip_win32
828 828 def test_script_bg_out():
829 829 ip = get_ipython()
830 830 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
831 831
832 832 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
833 833 ip.user_ns['output'].close()
834 834
835 835 @dec.skip_win32
836 836 def test_script_bg_err():
837 837 ip = get_ipython()
838 838 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
839 839 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
840 840 ip.user_ns['error'].close()
841 841
842 842 @dec.skip_win32
843 843 def test_script_bg_out_err():
844 844 ip = get_ipython()
845 845 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
846 846 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
847 847 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
848 848 ip.user_ns['output'].close()
849 849 ip.user_ns['error'].close()
850 850
851 851 def test_script_defaults():
852 852 ip = get_ipython()
853 853 for cmd in ['sh', 'bash', 'perl', 'ruby']:
854 854 try:
855 855 find_cmd(cmd)
856 856 except Exception:
857 857 pass
858 858 else:
859 859 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
860 860
861 861
862 862 @magics_class
863 863 class FooFoo(Magics):
864 864 """class with both %foo and %%foo magics"""
865 865 @line_magic('foo')
866 866 def line_foo(self, line):
867 867 "I am line foo"
868 868 pass
869 869
870 870 @cell_magic("foo")
871 871 def cell_foo(self, line, cell):
872 872 "I am cell foo, not line foo"
873 873 pass
874 874
875 875 def test_line_cell_info():
876 876 """%%foo and %foo magics are distinguishable to inspect"""
877 877 ip = get_ipython()
878 878 ip.magics_manager.register(FooFoo)
879 879 oinfo = ip.object_inspect('foo')
880 880 nt.assert_true(oinfo['found'])
881 881 nt.assert_true(oinfo['ismagic'])
882 882
883 883 oinfo = ip.object_inspect('%%foo')
884 884 nt.assert_true(oinfo['found'])
885 885 nt.assert_true(oinfo['ismagic'])
886 886 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
887 887
888 888 oinfo = ip.object_inspect('%foo')
889 889 nt.assert_true(oinfo['found'])
890 890 nt.assert_true(oinfo['ismagic'])
891 891 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
892 892
893 893 def test_multiple_magics():
894 894 ip = get_ipython()
895 895 foo1 = FooFoo(ip)
896 896 foo2 = FooFoo(ip)
897 897 mm = ip.magics_manager
898 898 mm.register(foo1)
899 899 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
900 900 mm.register(foo2)
901 901 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
902 902
903 903 def test_alias_magic():
904 904 """Test %alias_magic."""
905 905 ip = get_ipython()
906 906 mm = ip.magics_manager
907 907
908 908 # Basic operation: both cell and line magics are created, if possible.
909 909 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
910 910 nt.assert_in('timeit_alias', mm.magics['line'])
911 911 nt.assert_in('timeit_alias', mm.magics['cell'])
912 912
913 913 # --cell is specified, line magic not created.
914 914 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
915 915 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
916 916 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
917 917
918 918 # Test that line alias is created successfully.
919 919 ip.run_line_magic('alias_magic', '--line env_alias env')
920 920 nt.assert_equal(ip.run_line_magic('env', ''),
921 921 ip.run_line_magic('env_alias', ''))
922 922
923 923 # Test that line alias with parameters passed in is created successfully.
924 924 ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3'))
925 925 nt.assert_in('history_alias', mm.magics['line'])
926 926
927 927
928 928 def test_save():
929 929 """Test %save."""
930 930 ip = get_ipython()
931 931 ip.history_manager.reset() # Clear any existing history.
932 932 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
933 933 for i, cmd in enumerate(cmds, start=1):
934 934 ip.history_manager.store_inputs(i, cmd)
935 935 with TemporaryDirectory() as tmpdir:
936 936 file = os.path.join(tmpdir, "testsave.py")
937 937 ip.run_line_magic("save", "%s 1-10" % file)
938 938 with open(file) as f:
939 939 content = f.read()
940 940 nt.assert_equal(content.count(cmds[0]), 1)
941 941 nt.assert_in('coding: utf-8', content)
942 942 ip.run_line_magic("save", "-a %s 1-10" % file)
943 943 with open(file) as f:
944 944 content = f.read()
945 945 nt.assert_equal(content.count(cmds[0]), 2)
946 946 nt.assert_in('coding: utf-8', content)
947 947
948 948
949 949 def test_store():
950 950 """Test %store."""
951 951 ip = get_ipython()
952 952 ip.run_line_magic('load_ext', 'storemagic')
953 953
954 954 # make sure the storage is empty
955 955 ip.run_line_magic('store', '-z')
956 956 ip.user_ns['var'] = 42
957 957 ip.run_line_magic('store', 'var')
958 958 ip.user_ns['var'] = 39
959 959 ip.run_line_magic('store', '-r')
960 960 nt.assert_equal(ip.user_ns['var'], 42)
961 961
962 962 ip.run_line_magic('store', '-d var')
963 963 ip.user_ns['var'] = 39
964 964 ip.run_line_magic('store' , '-r')
965 965 nt.assert_equal(ip.user_ns['var'], 39)
966 966
967 967
968 968 def _run_edit_test(arg_s, exp_filename=None,
969 969 exp_lineno=-1,
970 970 exp_contents=None,
971 971 exp_is_temp=None):
972 972 ip = get_ipython()
973 973 M = code.CodeMagics(ip)
974 974 last_call = ['','']
975 975 opts,args = M.parse_options(arg_s,'prxn:')
976 976 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
977 977
978 978 if exp_filename is not None:
979 979 nt.assert_equal(exp_filename, filename)
980 980 if exp_contents is not None:
981 981 with io.open(filename, 'r', encoding='utf-8') as f:
982 982 contents = f.read()
983 983 nt.assert_equal(exp_contents, contents)
984 984 if exp_lineno != -1:
985 985 nt.assert_equal(exp_lineno, lineno)
986 986 if exp_is_temp is not None:
987 987 nt.assert_equal(exp_is_temp, is_temp)
988 988
989 989
990 990 def test_edit_interactive():
991 991 """%edit on interactively defined objects"""
992 992 ip = get_ipython()
993 993 n = ip.execution_count
994 994 ip.run_cell(u"def foo(): return 1", store_history=True)
995 995
996 996 try:
997 997 _run_edit_test("foo")
998 998 except code.InteractivelyDefined as e:
999 999 nt.assert_equal(e.index, n)
1000 1000 else:
1001 1001 raise AssertionError("Should have raised InteractivelyDefined")
1002 1002
1003 1003
1004 1004 def test_edit_cell():
1005 1005 """%edit [cell id]"""
1006 1006 ip = get_ipython()
1007 1007
1008 1008 ip.run_cell(u"def foo(): return 1", store_history=True)
1009 1009
1010 1010 # test
1011 1011 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1012 1012
1013 1013 def test_bookmark():
1014 1014 ip = get_ipython()
1015 1015 ip.run_line_magic('bookmark', 'bmname')
1016 1016 with tt.AssertPrints('bmname'):
1017 1017 ip.run_line_magic('bookmark', '-l')
1018 1018 ip.run_line_magic('bookmark', '-d bmname')
1019 1019
1020 1020 def test_ls_magic():
1021 1021 ip = get_ipython()
1022 1022 json_formatter = ip.display_formatter.formatters['application/json']
1023 1023 json_formatter.enabled = True
1024 1024 lsmagic = ip.magic('lsmagic')
1025 1025 with warnings.catch_warnings(record=True) as w:
1026 1026 j = json_formatter(lsmagic)
1027 1027 nt.assert_equal(sorted(j), ['cell', 'line'])
1028 1028 nt.assert_equal(w, []) # no warnings
1029 1029
1030 1030 def test_strip_initial_indent():
1031 1031 def sii(s):
1032 1032 lines = s.splitlines()
1033 1033 return '\n'.join(code.strip_initial_indent(lines))
1034 1034
1035 1035 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
1036 1036 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
1037 1037 nt.assert_equal(sii("a\n b"), "a\n b")
1038 1038
1039 1039 def test_logging_magic_quiet_from_arg():
1040 1040 _ip.config.LoggingMagics.quiet = False
1041 1041 lm = logging.LoggingMagics(shell=_ip)
1042 1042 with TemporaryDirectory() as td:
1043 1043 try:
1044 1044 with tt.AssertNotPrints(re.compile("Activating.*")):
1045 1045 lm.logstart('-q {}'.format(
1046 1046 os.path.join(td, "quiet_from_arg.log")))
1047 1047 finally:
1048 1048 _ip.logger.logstop()
1049 1049
1050 1050 def test_logging_magic_quiet_from_config():
1051 1051 _ip.config.LoggingMagics.quiet = True
1052 1052 lm = logging.LoggingMagics(shell=_ip)
1053 1053 with TemporaryDirectory() as td:
1054 1054 try:
1055 1055 with tt.AssertNotPrints(re.compile("Activating.*")):
1056 1056 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1057 1057 finally:
1058 1058 _ip.logger.logstop()
1059 1059
1060 1060 def test_logging_magic_not_quiet():
1061 1061 _ip.config.LoggingMagics.quiet = False
1062 1062 lm = logging.LoggingMagics(shell=_ip)
1063 1063 with TemporaryDirectory() as td:
1064 1064 try:
1065 1065 with tt.AssertPrints(re.compile("Activating.*")):
1066 1066 lm.logstart(os.path.join(td, "not_quiet.log"))
1067 1067 finally:
1068 1068 _ip.logger.logstop()
1069 1069
1070 1070 ##
1071 1071 # this is slow, put at the end for local testing.
1072 1072 ##
1073 1073 def test_timeit_arguments():
1074 1074 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1075 1075 if sys.version_info < (3,7):
1076 1076 _ip.magic("timeit ('#')")
1077 1077 else:
1078 1078 # 3.7 optimize no-op statement like above out, and complain there is
1079 1079 # nothing in the for loop.
1080 1080 _ip.magic("timeit a=('#')")
General Comments 0
You need to be logged in to leave comments. Login now