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