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