##// END OF EJS Templates
Call invalidate_caches() when testing installing extension.
Thomas Kluyver -
Show More
@@ -1,547 +1,554 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6 from __future__ import absolute_import
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11
12 12 import io
13 13 import os
14 14 import sys
15 15 from StringIO import StringIO
16 16 from unittest import TestCase
17 17
18 try:
19 from importlib import invalidate_caches # Required from Python 3.3
20 except ImportError:
21 def invalidate_caches():
22 pass
23
18 24 import nose.tools as nt
19 25
20 26 from IPython.core import magic
21 27 from IPython.core.magic import (Magics, magics_class, line_magic,
22 28 cell_magic, line_cell_magic,
23 29 register_line_magic, register_cell_magic,
24 30 register_line_cell_magic)
25 31 from IPython.core.magics import execution
26 32 from IPython.nbformat.v3.tests.nbexamples import nb0
27 33 from IPython.nbformat import current
28 34 from IPython.testing import decorators as dec
29 35 from IPython.testing import tools as tt
30 36 from IPython.utils import py3compat
31 37 from IPython.utils.tempdir import TemporaryDirectory
32 38
33 39 #-----------------------------------------------------------------------------
34 40 # Test functions begin
35 41 #-----------------------------------------------------------------------------
36 42
37 43 @magic.magics_class
38 44 class DummyMagics(magic.Magics): pass
39 45
40 46 def test_rehashx():
41 47 # clear up everything
42 48 _ip = get_ipython()
43 49 _ip.alias_manager.alias_table.clear()
44 50 del _ip.db['syscmdlist']
45 51
46 52 _ip.magic('rehashx')
47 53 # Practically ALL ipython development systems will have more than 10 aliases
48 54
49 55 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
50 56 for key, val in _ip.alias_manager.alias_table.iteritems():
51 57 # we must strip dots from alias names
52 58 nt.assert_true('.' not in key)
53 59
54 60 # rehashx must fill up syscmdlist
55 61 scoms = _ip.db['syscmdlist']
56 62 yield (nt.assert_true, len(scoms) > 10)
57 63
58 64
59 65 def test_magic_parse_options():
60 66 """Test that we don't mangle paths when parsing magic options."""
61 67 ip = get_ipython()
62 68 path = 'c:\\x'
63 69 m = DummyMagics(ip)
64 70 opts = m.parse_options('-f %s' % path,'f:')[0]
65 71 # argv splitting is os-dependent
66 72 if os.name == 'posix':
67 73 expected = 'c:x'
68 74 else:
69 75 expected = path
70 76 nt.assert_equals(opts['f'], expected)
71 77
72 78
73 79 @dec.skip_without('sqlite3')
74 80 def doctest_hist_f():
75 81 """Test %hist -f with temporary filename.
76 82
77 83 In [9]: import tempfile
78 84
79 85 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
80 86
81 87 In [11]: %hist -nl -f $tfile 3
82 88
83 89 In [13]: import os; os.unlink(tfile)
84 90 """
85 91
86 92
87 93 @dec.skip_without('sqlite3')
88 94 def doctest_hist_r():
89 95 """Test %hist -r
90 96
91 97 XXX - This test is not recording the output correctly. For some reason, in
92 98 testing mode the raw history isn't getting populated. No idea why.
93 99 Disabling the output checking for now, though at least we do run it.
94 100
95 101 In [1]: 'hist' in _ip.lsmagic()
96 102 Out[1]: True
97 103
98 104 In [2]: x=1
99 105
100 106 In [3]: %hist -rl 2
101 107 x=1 # random
102 108 %hist -r 2
103 109 """
104 110
105 111
106 112 @dec.skip_without('sqlite3')
107 113 def doctest_hist_op():
108 114 """Test %hist -op
109 115
110 116 In [1]: class b(float):
111 117 ...: pass
112 118 ...:
113 119
114 120 In [2]: class s(object):
115 121 ...: def __str__(self):
116 122 ...: return 's'
117 123 ...:
118 124
119 125 In [3]:
120 126
121 127 In [4]: class r(b):
122 128 ...: def __repr__(self):
123 129 ...: return 'r'
124 130 ...:
125 131
126 132 In [5]: class sr(s,r): pass
127 133 ...:
128 134
129 135 In [6]:
130 136
131 137 In [7]: bb=b()
132 138
133 139 In [8]: ss=s()
134 140
135 141 In [9]: rr=r()
136 142
137 143 In [10]: ssrr=sr()
138 144
139 145 In [11]: 4.5
140 146 Out[11]: 4.5
141 147
142 148 In [12]: str(ss)
143 149 Out[12]: 's'
144 150
145 151 In [13]:
146 152
147 153 In [14]: %hist -op
148 154 >>> class b:
149 155 ... pass
150 156 ...
151 157 >>> class s(b):
152 158 ... def __str__(self):
153 159 ... return 's'
154 160 ...
155 161 >>>
156 162 >>> class r(b):
157 163 ... def __repr__(self):
158 164 ... return 'r'
159 165 ...
160 166 >>> class sr(s,r): pass
161 167 >>>
162 168 >>> bb=b()
163 169 >>> ss=s()
164 170 >>> rr=r()
165 171 >>> ssrr=sr()
166 172 >>> 4.5
167 173 4.5
168 174 >>> str(ss)
169 175 's'
170 176 >>>
171 177 """
172 178
173 179
174 180 @dec.skip_without('sqlite3')
175 181 def test_macro():
176 182 ip = get_ipython()
177 183 ip.history_manager.reset() # Clear any existing history.
178 184 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
179 185 for i, cmd in enumerate(cmds, start=1):
180 186 ip.history_manager.store_inputs(i, cmd)
181 187 ip.magic("macro test 1-3")
182 188 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
183 189
184 190 # List macros.
185 191 assert "test" in ip.magic("macro")
186 192
187 193
188 194 @dec.skip_without('sqlite3')
189 195 def test_macro_run():
190 196 """Test that we can run a multi-line macro successfully."""
191 197 ip = get_ipython()
192 198 ip.history_manager.reset()
193 199 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
194 200 "%macro test 2-3"]
195 201 for cmd in cmds:
196 202 ip.run_cell(cmd, store_history=True)
197 203 nt.assert_equal(ip.user_ns["test"].value,
198 204 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
199 205 with tt.AssertPrints("12"):
200 206 ip.run_cell("test")
201 207 with tt.AssertPrints("13"):
202 208 ip.run_cell("test")
203 209
204 210
205 211 @dec.skipif_not_numpy
206 212 def test_numpy_reset_array_undec():
207 213 "Test '%reset array' functionality"
208 214 _ip.ex('import numpy as np')
209 215 _ip.ex('a = np.empty(2)')
210 216 yield (nt.assert_true, 'a' in _ip.user_ns)
211 217 _ip.magic('reset -f array')
212 218 yield (nt.assert_false, 'a' in _ip.user_ns)
213 219
214 220 def test_reset_out():
215 221 "Test '%reset out' magic"
216 222 _ip.run_cell("parrot = 'dead'", store_history=True)
217 223 # test '%reset -f out', make an Out prompt
218 224 _ip.run_cell("parrot", store_history=True)
219 225 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
220 226 _ip.magic('reset -f out')
221 227 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
222 228 nt.assert_true(len(_ip.user_ns['Out']) == 0)
223 229
224 230 def test_reset_in():
225 231 "Test '%reset in' magic"
226 232 # test '%reset -f in'
227 233 _ip.run_cell("parrot", store_history=True)
228 234 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
229 235 _ip.magic('%reset -f in')
230 236 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
231 237 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
232 238
233 239 def test_reset_dhist():
234 240 "Test '%reset dhist' magic"
235 241 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
236 242 _ip.magic('cd ' + os.path.dirname(nt.__file__))
237 243 _ip.magic('cd -')
238 244 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
239 245 _ip.magic('reset -f dhist')
240 246 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
241 247 _ip.run_cell("_dh = [d for d in tmp]") #restore
242 248
243 249 def test_reset_in_length():
244 250 "Test that '%reset in' preserves In[] length"
245 251 _ip.run_cell("print 'foo'")
246 252 _ip.run_cell("reset -f in")
247 253 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
248 254
249 255 def test_time():
250 256 _ip.magic('time None')
251 257
252 258 def test_tb_syntaxerror():
253 259 """test %tb after a SyntaxError"""
254 260 ip = get_ipython()
255 261 ip.run_cell("for")
256 262
257 263 # trap and validate stdout
258 264 save_stdout = sys.stdout
259 265 try:
260 266 sys.stdout = StringIO()
261 267 ip.run_cell("%tb")
262 268 out = sys.stdout.getvalue()
263 269 finally:
264 270 sys.stdout = save_stdout
265 271 # trim output, and only check the last line
266 272 last_line = out.rstrip().splitlines()[-1].strip()
267 273 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
268 274
269 275
270 276 @py3compat.doctest_refactor_print
271 277 def doctest_time():
272 278 """
273 279 In [10]: %time None
274 280 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
275 281 Wall time: 0.00 s
276 282
277 283 In [11]: def f(kmjy):
278 284 ....: %time print 2*kmjy
279 285
280 286 In [12]: f(3)
281 287 6
282 288 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
283 289 Wall time: 0.00 s
284 290 """
285 291
286 292
287 293 def test_doctest_mode():
288 294 "Toggle doctest_mode twice, it should be a no-op and run without error"
289 295 _ip.magic('doctest_mode')
290 296 _ip.magic('doctest_mode')
291 297
292 298
293 299 def test_parse_options():
294 300 """Tests for basic options parsing in magics."""
295 301 # These are only the most minimal of tests, more should be added later. At
296 302 # the very least we check that basic text/unicode calls work OK.
297 303 m = DummyMagics(_ip)
298 304 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
299 305 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
300 306
301 307
302 308 def test_dirops():
303 309 """Test various directory handling operations."""
304 310 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
305 311 curpath = os.getcwdu
306 312 startdir = os.getcwdu()
307 313 ipdir = os.path.realpath(_ip.ipython_dir)
308 314 try:
309 315 _ip.magic('cd "%s"' % ipdir)
310 316 nt.assert_equal(curpath(), ipdir)
311 317 _ip.magic('cd -')
312 318 nt.assert_equal(curpath(), startdir)
313 319 _ip.magic('pushd "%s"' % ipdir)
314 320 nt.assert_equal(curpath(), ipdir)
315 321 _ip.magic('popd')
316 322 nt.assert_equal(curpath(), startdir)
317 323 finally:
318 324 os.chdir(startdir)
319 325
320 326
321 327 def test_xmode():
322 328 # Calling xmode three times should be a no-op
323 329 xmode = _ip.InteractiveTB.mode
324 330 for i in range(3):
325 331 _ip.magic("xmode")
326 332 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
327 333
328 334 def test_reset_hard():
329 335 monitor = []
330 336 class A(object):
331 337 def __del__(self):
332 338 monitor.append(1)
333 339 def __repr__(self):
334 340 return "<A instance>"
335 341
336 342 _ip.user_ns["a"] = A()
337 343 _ip.run_cell("a")
338 344
339 345 nt.assert_equal(monitor, [])
340 346 _ip.magic("reset -f")
341 347 nt.assert_equal(monitor, [1])
342 348
343 349 class TestXdel(tt.TempFileMixin):
344 350 def test_xdel(self):
345 351 """Test that references from %run are cleared by xdel."""
346 352 src = ("class A(object):\n"
347 353 " monitor = []\n"
348 354 " def __del__(self):\n"
349 355 " self.monitor.append(1)\n"
350 356 "a = A()\n")
351 357 self.mktmp(src)
352 358 # %run creates some hidden references...
353 359 _ip.magic("run %s" % self.fname)
354 360 # ... as does the displayhook.
355 361 _ip.run_cell("a")
356 362
357 363 monitor = _ip.user_ns["A"].monitor
358 364 nt.assert_equal(monitor, [])
359 365
360 366 _ip.magic("xdel a")
361 367
362 368 # Check that a's __del__ method has been called.
363 369 nt.assert_equal(monitor, [1])
364 370
365 371 def doctest_who():
366 372 """doctest for %who
367 373
368 374 In [1]: %reset -f
369 375
370 376 In [2]: alpha = 123
371 377
372 378 In [3]: beta = 'beta'
373 379
374 380 In [4]: %who int
375 381 alpha
376 382
377 383 In [5]: %who str
378 384 beta
379 385
380 386 In [6]: %whos
381 387 Variable Type Data/Info
382 388 ----------------------------
383 389 alpha int 123
384 390 beta str beta
385 391
386 392 In [7]: %who_ls
387 393 Out[7]: ['alpha', 'beta']
388 394 """
389 395
390 396 def test_whos():
391 397 """Check that whos is protected against objects where repr() fails."""
392 398 class A(object):
393 399 def __repr__(self):
394 400 raise Exception()
395 401 _ip.user_ns['a'] = A()
396 402 _ip.magic("whos")
397 403
398 404 @py3compat.u_format
399 405 def doctest_precision():
400 406 """doctest for %precision
401 407
402 408 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
403 409
404 410 In [2]: %precision 5
405 411 Out[2]: {u}'%.5f'
406 412
407 413 In [3]: f.float_format
408 414 Out[3]: {u}'%.5f'
409 415
410 416 In [4]: %precision %e
411 417 Out[4]: {u}'%e'
412 418
413 419 In [5]: f(3.1415927)
414 420 Out[5]: {u}'3.141593e+00'
415 421 """
416 422
417 423 def test_psearch():
418 424 with tt.AssertPrints("dict.fromkeys"):
419 425 _ip.run_cell("dict.fr*?")
420 426
421 427 def test_timeit_shlex():
422 428 """test shlex issues with timeit (#1109)"""
423 429 _ip.ex("def f(*a,**kw): pass")
424 430 _ip.magic('timeit -n1 "this is a bug".count(" ")')
425 431 _ip.magic('timeit -r1 -n1 f(" ", 1)')
426 432 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
427 433 _ip.magic('timeit -r1 -n1 ("a " + "b")')
428 434 _ip.magic('timeit -r1 -n1 f("a " + "b")')
429 435 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
430 436
431 437
432 438 def test_timeit_arguments():
433 439 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
434 440 _ip.magic("timeit ('#')")
435 441
436 442
437 443 @dec.skipif(execution.profile is None)
438 444 def test_prun_quotes():
439 445 "Test that prun does not clobber string escapes (GH #1302)"
440 446 _ip.magic("prun -q x = '\t'")
441 447 nt.assert_equal(_ip.user_ns['x'], '\t')
442 448
443 449 def test_extension():
444 450 tmpdir = TemporaryDirectory()
445 451 orig_ipython_dir = _ip.ipython_dir
446 452 try:
447 453 _ip.ipython_dir = tmpdir.name
448 454 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
449 455 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
450 456 _ip.magic("install_ext %s" % url)
451 457 _ip.user_ns.pop('arq', None)
458 invalidate_caches() # Clear import caches
452 459 _ip.magic("load_ext daft_extension")
453 460 tt.assert_equal(_ip.user_ns['arq'], 185)
454 461 _ip.magic("unload_ext daft_extension")
455 462 assert 'arq' not in _ip.user_ns
456 463 finally:
457 464 _ip.ipython_dir = orig_ipython_dir
458 465
459 466 def test_notebook_export_json():
460 467 with TemporaryDirectory() as td:
461 468 outfile = os.path.join(td, "nb.ipynb")
462 469 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
463 470 _ip.magic("notebook -e %s" % outfile)
464 471
465 472 def test_notebook_export_py():
466 473 with TemporaryDirectory() as td:
467 474 outfile = os.path.join(td, "nb.py")
468 475 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
469 476 _ip.magic("notebook -e %s" % outfile)
470 477
471 478 def test_notebook_reformat_py():
472 479 with TemporaryDirectory() as td:
473 480 infile = os.path.join(td, "nb.ipynb")
474 481 with io.open(infile, 'w', encoding='utf-8') as f:
475 482 current.write(nb0, f, 'json')
476 483
477 484 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
478 485 _ip.magic("notebook -f py %s" % infile)
479 486
480 487 def test_notebook_reformat_json():
481 488 with TemporaryDirectory() as td:
482 489 infile = os.path.join(td, "nb.py")
483 490 with io.open(infile, 'w', encoding='utf-8') as f:
484 491 current.write(nb0, f, 'py')
485 492
486 493 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
487 494 _ip.magic("notebook -f ipynb %s" % infile)
488 495 _ip.magic("notebook -f json %s" % infile)
489 496
490 497 def test_env():
491 498 env = _ip.magic("env")
492 499 assert isinstance(env, dict), type(env)
493 500
494 501
495 502 class CellMagicTestCase(TestCase):
496 503
497 504 def check_ident(self, magic):
498 505 # Manually called, we get the result
499 506 out = _ip.run_cell_magic(magic, 'a', 'b')
500 507 nt.assert_equals(out, ('a','b'))
501 508 # Via run_cell, it goes into the user's namespace via displayhook
502 509 _ip.run_cell('%%' + magic +' c\nd')
503 510 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
504 511
505 512 def test_cell_magic_func_deco(self):
506 513 "Cell magic using simple decorator"
507 514 @register_cell_magic
508 515 def cellm(line, cell):
509 516 return line, cell
510 517
511 518 self.check_ident('cellm')
512 519
513 520 def test_cell_magic_reg(self):
514 521 "Cell magic manually registered"
515 522 def cellm(line, cell):
516 523 return line, cell
517 524
518 525 _ip.register_magic_function(cellm, 'cell', 'cellm2')
519 526 self.check_ident('cellm2')
520 527
521 528 def test_cell_magic_class(self):
522 529 "Cell magics declared via a class"
523 530 @magics_class
524 531 class MyMagics(Magics):
525 532
526 533 @cell_magic
527 534 def cellm3(self, line, cell):
528 535 return line, cell
529 536
530 537 _ip.register_magics(MyMagics)
531 538 self.check_ident('cellm3')
532 539
533 540 def test_cell_magic_class2(self):
534 541 "Cell magics declared via a class, #2"
535 542 @magics_class
536 543 class MyMagics2(Magics):
537 544
538 545 @cell_magic('cellm4')
539 546 def cellm33(self, line, cell):
540 547 return line, cell
541 548
542 549 _ip.register_magics(MyMagics2)
543 550 self.check_ident('cellm4')
544 551 # Check that nothing is registered as 'cellm33'
545 552 c33 = _ip.find_cell_magic('cellm33')
546 553 nt.assert_equals(c33, None)
547 554
General Comments 0
You need to be logged in to leave comments. Login now