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