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