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