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