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