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