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