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