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