##// END OF EJS Templates
Add test that macros are affected by AST transformations
Thomas Kluyver -
Show More
@@ -1,532 +1,542 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Historically the main classes in interactiveshell have been under-tested. This
4 Historically the main classes in interactiveshell have been under-tested. This
5 module should grow as many single-method tests as possible to trap many of the
5 module should grow as many single-method tests as possible to trap many of the
6 recurring bugs we seem to encounter with high-level interaction.
6 recurring bugs we seem to encounter with high-level interaction.
7
7
8 Authors
8 Authors
9 -------
9 -------
10 * Fernando Perez
10 * Fernando Perez
11 """
11 """
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2011 The IPython Development Team
13 # Copyright (C) 2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # stdlib
22 # stdlib
23 import ast
23 import ast
24 import os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27 import tempfile
27 import tempfile
28 import unittest
28 import unittest
29 from os.path import join
29 from os.path import join
30 from StringIO import StringIO
30 from StringIO import StringIO
31
31
32 # third-party
32 # third-party
33 import nose.tools as nt
33 import nose.tools as nt
34
34
35 # Our own
35 # Our own
36 from IPython.testing.decorators import skipif
36 from IPython.testing.decorators import skipif
37 from IPython.testing import tools as tt
37 from IPython.testing import tools as tt
38 from IPython.utils import io
38 from IPython.utils import io
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Globals
41 # Globals
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # This is used by every single test, no point repeating it ad nauseam
43 # This is used by every single test, no point repeating it ad nauseam
44 ip = get_ipython()
44 ip = get_ipython()
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Tests
47 # Tests
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class InteractiveShellTestCase(unittest.TestCase):
50 class InteractiveShellTestCase(unittest.TestCase):
51 def test_naked_string_cells(self):
51 def test_naked_string_cells(self):
52 """Test that cells with only naked strings are fully executed"""
52 """Test that cells with only naked strings are fully executed"""
53 # First, single-line inputs
53 # First, single-line inputs
54 ip.run_cell('"a"\n')
54 ip.run_cell('"a"\n')
55 self.assertEqual(ip.user_ns['_'], 'a')
55 self.assertEqual(ip.user_ns['_'], 'a')
56 # And also multi-line cells
56 # And also multi-line cells
57 ip.run_cell('"""a\nb"""\n')
57 ip.run_cell('"""a\nb"""\n')
58 self.assertEqual(ip.user_ns['_'], 'a\nb')
58 self.assertEqual(ip.user_ns['_'], 'a\nb')
59
59
60 def test_run_empty_cell(self):
60 def test_run_empty_cell(self):
61 """Just make sure we don't get a horrible error with a blank
61 """Just make sure we don't get a horrible error with a blank
62 cell of input. Yes, I did overlook that."""
62 cell of input. Yes, I did overlook that."""
63 old_xc = ip.execution_count
63 old_xc = ip.execution_count
64 ip.run_cell('')
64 ip.run_cell('')
65 self.assertEqual(ip.execution_count, old_xc)
65 self.assertEqual(ip.execution_count, old_xc)
66
66
67 def test_run_cell_multiline(self):
67 def test_run_cell_multiline(self):
68 """Multi-block, multi-line cells must execute correctly.
68 """Multi-block, multi-line cells must execute correctly.
69 """
69 """
70 src = '\n'.join(["x=1",
70 src = '\n'.join(["x=1",
71 "y=2",
71 "y=2",
72 "if 1:",
72 "if 1:",
73 " x += 1",
73 " x += 1",
74 " y += 1",])
74 " y += 1",])
75 ip.run_cell(src)
75 ip.run_cell(src)
76 self.assertEqual(ip.user_ns['x'], 2)
76 self.assertEqual(ip.user_ns['x'], 2)
77 self.assertEqual(ip.user_ns['y'], 3)
77 self.assertEqual(ip.user_ns['y'], 3)
78
78
79 def test_multiline_string_cells(self):
79 def test_multiline_string_cells(self):
80 "Code sprinkled with multiline strings should execute (GH-306)"
80 "Code sprinkled with multiline strings should execute (GH-306)"
81 ip.run_cell('tmp=0')
81 ip.run_cell('tmp=0')
82 self.assertEqual(ip.user_ns['tmp'], 0)
82 self.assertEqual(ip.user_ns['tmp'], 0)
83 ip.run_cell('tmp=1;"""a\nb"""\n')
83 ip.run_cell('tmp=1;"""a\nb"""\n')
84 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(ip.user_ns['tmp'], 1)
85
85
86 def test_dont_cache_with_semicolon(self):
86 def test_dont_cache_with_semicolon(self):
87 "Ending a line with semicolon should not cache the returned object (GH-307)"
87 "Ending a line with semicolon should not cache the returned object (GH-307)"
88 oldlen = len(ip.user_ns['Out'])
88 oldlen = len(ip.user_ns['Out'])
89 a = ip.run_cell('1;', store_history=True)
89 a = ip.run_cell('1;', store_history=True)
90 newlen = len(ip.user_ns['Out'])
90 newlen = len(ip.user_ns['Out'])
91 self.assertEqual(oldlen, newlen)
91 self.assertEqual(oldlen, newlen)
92 #also test the default caching behavior
92 #also test the default caching behavior
93 ip.run_cell('1', store_history=True)
93 ip.run_cell('1', store_history=True)
94 newlen = len(ip.user_ns['Out'])
94 newlen = len(ip.user_ns['Out'])
95 self.assertEqual(oldlen+1, newlen)
95 self.assertEqual(oldlen+1, newlen)
96
96
97 def test_In_variable(self):
97 def test_In_variable(self):
98 "Verify that In variable grows with user input (GH-284)"
98 "Verify that In variable grows with user input (GH-284)"
99 oldlen = len(ip.user_ns['In'])
99 oldlen = len(ip.user_ns['In'])
100 ip.run_cell('1;', store_history=True)
100 ip.run_cell('1;', store_history=True)
101 newlen = len(ip.user_ns['In'])
101 newlen = len(ip.user_ns['In'])
102 self.assertEqual(oldlen+1, newlen)
102 self.assertEqual(oldlen+1, newlen)
103 self.assertEqual(ip.user_ns['In'][-1],'1;')
103 self.assertEqual(ip.user_ns['In'][-1],'1;')
104
104
105 def test_magic_names_in_string(self):
105 def test_magic_names_in_string(self):
106 ip.run_cell('a = """\n%exit\n"""')
106 ip.run_cell('a = """\n%exit\n"""')
107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
108
108
109 def test_alias_crash(self):
109 def test_alias_crash(self):
110 """Errors in prefilter can't crash IPython"""
110 """Errors in prefilter can't crash IPython"""
111 ip.run_cell('%alias parts echo first %s second %s')
111 ip.run_cell('%alias parts echo first %s second %s')
112 # capture stderr:
112 # capture stderr:
113 save_err = io.stderr
113 save_err = io.stderr
114 io.stderr = StringIO()
114 io.stderr = StringIO()
115 ip.run_cell('parts 1')
115 ip.run_cell('parts 1')
116 err = io.stderr.getvalue()
116 err = io.stderr.getvalue()
117 io.stderr = save_err
117 io.stderr = save_err
118 self.assertEqual(err.split(':')[0], 'ERROR')
118 self.assertEqual(err.split(':')[0], 'ERROR')
119
119
120 def test_trailing_newline(self):
120 def test_trailing_newline(self):
121 """test that running !(command) does not raise a SyntaxError"""
121 """test that running !(command) does not raise a SyntaxError"""
122 ip.run_cell('!(true)\n', False)
122 ip.run_cell('!(true)\n', False)
123 ip.run_cell('!(true)\n\n\n', False)
123 ip.run_cell('!(true)\n\n\n', False)
124
124
125 def test_gh_597(self):
125 def test_gh_597(self):
126 """Pretty-printing lists of objects with non-ascii reprs may cause
126 """Pretty-printing lists of objects with non-ascii reprs may cause
127 problems."""
127 problems."""
128 class Spam(object):
128 class Spam(object):
129 def __repr__(self):
129 def __repr__(self):
130 return "\xe9"*50
130 return "\xe9"*50
131 import IPython.core.formatters
131 import IPython.core.formatters
132 f = IPython.core.formatters.PlainTextFormatter()
132 f = IPython.core.formatters.PlainTextFormatter()
133 f([Spam(),Spam()])
133 f([Spam(),Spam()])
134
134
135
135
136 def test_future_flags(self):
136 def test_future_flags(self):
137 """Check that future flags are used for parsing code (gh-777)"""
137 """Check that future flags are used for parsing code (gh-777)"""
138 ip.run_cell('from __future__ import print_function')
138 ip.run_cell('from __future__ import print_function')
139 try:
139 try:
140 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
140 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
141 assert 'prfunc_return_val' in ip.user_ns
141 assert 'prfunc_return_val' in ip.user_ns
142 finally:
142 finally:
143 # Reset compiler flags so we don't mess up other tests.
143 # Reset compiler flags so we don't mess up other tests.
144 ip.compile.reset_compiler_flags()
144 ip.compile.reset_compiler_flags()
145
145
146 def test_future_unicode(self):
146 def test_future_unicode(self):
147 """Check that unicode_literals is imported from __future__ (gh #786)"""
147 """Check that unicode_literals is imported from __future__ (gh #786)"""
148 try:
148 try:
149 ip.run_cell(u'byte_str = "a"')
149 ip.run_cell(u'byte_str = "a"')
150 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
150 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
151 ip.run_cell('from __future__ import unicode_literals')
151 ip.run_cell('from __future__ import unicode_literals')
152 ip.run_cell(u'unicode_str = "a"')
152 ip.run_cell(u'unicode_str = "a"')
153 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
153 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
154 finally:
154 finally:
155 # Reset compiler flags so we don't mess up other tests.
155 # Reset compiler flags so we don't mess up other tests.
156 ip.compile.reset_compiler_flags()
156 ip.compile.reset_compiler_flags()
157
157
158 def test_can_pickle(self):
158 def test_can_pickle(self):
159 "Can we pickle objects defined interactively (GH-29)"
159 "Can we pickle objects defined interactively (GH-29)"
160 ip = get_ipython()
160 ip = get_ipython()
161 ip.reset()
161 ip.reset()
162 ip.run_cell(("class Mylist(list):\n"
162 ip.run_cell(("class Mylist(list):\n"
163 " def __init__(self,x=[]):\n"
163 " def __init__(self,x=[]):\n"
164 " list.__init__(self,x)"))
164 " list.__init__(self,x)"))
165 ip.run_cell("w=Mylist([1,2,3])")
165 ip.run_cell("w=Mylist([1,2,3])")
166
166
167 from cPickle import dumps
167 from cPickle import dumps
168
168
169 # We need to swap in our main module - this is only necessary
169 # We need to swap in our main module - this is only necessary
170 # inside the test framework, because IPython puts the interactive module
170 # inside the test framework, because IPython puts the interactive module
171 # in place (but the test framework undoes this).
171 # in place (but the test framework undoes this).
172 _main = sys.modules['__main__']
172 _main = sys.modules['__main__']
173 sys.modules['__main__'] = ip.user_module
173 sys.modules['__main__'] = ip.user_module
174 try:
174 try:
175 res = dumps(ip.user_ns["w"])
175 res = dumps(ip.user_ns["w"])
176 finally:
176 finally:
177 sys.modules['__main__'] = _main
177 sys.modules['__main__'] = _main
178 self.assertTrue(isinstance(res, bytes))
178 self.assertTrue(isinstance(res, bytes))
179
179
180 def test_global_ns(self):
180 def test_global_ns(self):
181 "Code in functions must be able to access variables outside them."
181 "Code in functions must be able to access variables outside them."
182 ip = get_ipython()
182 ip = get_ipython()
183 ip.run_cell("a = 10")
183 ip.run_cell("a = 10")
184 ip.run_cell(("def f(x):\n"
184 ip.run_cell(("def f(x):\n"
185 " return x + a"))
185 " return x + a"))
186 ip.run_cell("b = f(12)")
186 ip.run_cell("b = f(12)")
187 self.assertEqual(ip.user_ns["b"], 22)
187 self.assertEqual(ip.user_ns["b"], 22)
188
188
189 def test_bad_custom_tb(self):
189 def test_bad_custom_tb(self):
190 """Check that InteractiveShell is protected from bad custom exception handlers"""
190 """Check that InteractiveShell is protected from bad custom exception handlers"""
191 from IPython.utils import io
191 from IPython.utils import io
192 save_stderr = io.stderr
192 save_stderr = io.stderr
193 try:
193 try:
194 # capture stderr
194 # capture stderr
195 io.stderr = StringIO()
195 io.stderr = StringIO()
196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
197 self.assertEqual(ip.custom_exceptions, (IOError,))
197 self.assertEqual(ip.custom_exceptions, (IOError,))
198 ip.run_cell(u'raise IOError("foo")')
198 ip.run_cell(u'raise IOError("foo")')
199 self.assertEqual(ip.custom_exceptions, ())
199 self.assertEqual(ip.custom_exceptions, ())
200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
201 finally:
201 finally:
202 io.stderr = save_stderr
202 io.stderr = save_stderr
203
203
204 def test_bad_custom_tb_return(self):
204 def test_bad_custom_tb_return(self):
205 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
205 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 from IPython.utils import io
206 from IPython.utils import io
207 save_stderr = io.stderr
207 save_stderr = io.stderr
208 try:
208 try:
209 # capture stderr
209 # capture stderr
210 io.stderr = StringIO()
210 io.stderr = StringIO()
211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 self.assertEqual(ip.custom_exceptions, (NameError,))
212 self.assertEqual(ip.custom_exceptions, (NameError,))
213 ip.run_cell(u'a=abracadabra')
213 ip.run_cell(u'a=abracadabra')
214 self.assertEqual(ip.custom_exceptions, ())
214 self.assertEqual(ip.custom_exceptions, ())
215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 finally:
216 finally:
217 io.stderr = save_stderr
217 io.stderr = save_stderr
218
218
219 def test_drop_by_id(self):
219 def test_drop_by_id(self):
220 myvars = {"a":object(), "b":object(), "c": object()}
220 myvars = {"a":object(), "b":object(), "c": object()}
221 ip.push(myvars, interactive=False)
221 ip.push(myvars, interactive=False)
222 for name in myvars:
222 for name in myvars:
223 assert name in ip.user_ns, name
223 assert name in ip.user_ns, name
224 assert name in ip.user_ns_hidden, name
224 assert name in ip.user_ns_hidden, name
225 ip.user_ns['b'] = 12
225 ip.user_ns['b'] = 12
226 ip.drop_by_id(myvars)
226 ip.drop_by_id(myvars)
227 for name in ["a", "c"]:
227 for name in ["a", "c"]:
228 assert name not in ip.user_ns, name
228 assert name not in ip.user_ns, name
229 assert name not in ip.user_ns_hidden, name
229 assert name not in ip.user_ns_hidden, name
230 assert ip.user_ns['b'] == 12
230 assert ip.user_ns['b'] == 12
231 ip.reset()
231 ip.reset()
232
232
233 def test_var_expand(self):
233 def test_var_expand(self):
234 ip.user_ns['f'] = u'Ca\xf1o'
234 ip.user_ns['f'] = u'Ca\xf1o'
235 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
235 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
236 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
236 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
237 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
237 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
238 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
238 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
239
239
240 ip.user_ns['f'] = b'Ca\xc3\xb1o'
240 ip.user_ns['f'] = b'Ca\xc3\xb1o'
241 # This should not raise any exception:
241 # This should not raise any exception:
242 ip.var_expand(u'echo $f')
242 ip.var_expand(u'echo $f')
243
243
244 def test_var_expand_local(self):
244 def test_var_expand_local(self):
245 """Test local variable expansion in !system and %magic calls"""
245 """Test local variable expansion in !system and %magic calls"""
246 # !system
246 # !system
247 ip.run_cell('def test():\n'
247 ip.run_cell('def test():\n'
248 ' lvar = "ttt"\n'
248 ' lvar = "ttt"\n'
249 ' ret = !echo {lvar}\n'
249 ' ret = !echo {lvar}\n'
250 ' return ret[0]\n')
250 ' return ret[0]\n')
251 res = ip.user_ns['test']()
251 res = ip.user_ns['test']()
252 nt.assert_in('ttt', res)
252 nt.assert_in('ttt', res)
253
253
254 # %magic
254 # %magic
255 ip.run_cell('def makemacro():\n'
255 ip.run_cell('def makemacro():\n'
256 ' macroname = "macro_var_expand_locals"\n'
256 ' macroname = "macro_var_expand_locals"\n'
257 ' %macro {macroname} codestr\n')
257 ' %macro {macroname} codestr\n')
258 ip.user_ns['codestr'] = "str(12)"
258 ip.user_ns['codestr'] = "str(12)"
259 ip.run_cell('makemacro()')
259 ip.run_cell('makemacro()')
260 nt.assert_in('macro_var_expand_locals', ip.user_ns)
260 nt.assert_in('macro_var_expand_locals', ip.user_ns)
261
261
262 def test_bad_var_expand(self):
262 def test_bad_var_expand(self):
263 """var_expand on invalid formats shouldn't raise"""
263 """var_expand on invalid formats shouldn't raise"""
264 # SyntaxError
264 # SyntaxError
265 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
265 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
266 # NameError
266 # NameError
267 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
267 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
268 # ZeroDivisionError
268 # ZeroDivisionError
269 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
269 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
270
270
271 def test_silent_nopostexec(self):
271 def test_silent_nopostexec(self):
272 """run_cell(silent=True) doesn't invoke post-exec funcs"""
272 """run_cell(silent=True) doesn't invoke post-exec funcs"""
273 d = dict(called=False)
273 d = dict(called=False)
274 def set_called():
274 def set_called():
275 d['called'] = True
275 d['called'] = True
276
276
277 ip.register_post_execute(set_called)
277 ip.register_post_execute(set_called)
278 ip.run_cell("1", silent=True)
278 ip.run_cell("1", silent=True)
279 self.assertFalse(d['called'])
279 self.assertFalse(d['called'])
280 # double-check that non-silent exec did what we expected
280 # double-check that non-silent exec did what we expected
281 # silent to avoid
281 # silent to avoid
282 ip.run_cell("1")
282 ip.run_cell("1")
283 self.assertTrue(d['called'])
283 self.assertTrue(d['called'])
284 # remove post-exec
284 # remove post-exec
285 ip._post_execute.pop(set_called)
285 ip._post_execute.pop(set_called)
286
286
287 def test_silent_noadvance(self):
287 def test_silent_noadvance(self):
288 """run_cell(silent=True) doesn't advance execution_count"""
288 """run_cell(silent=True) doesn't advance execution_count"""
289 ec = ip.execution_count
289 ec = ip.execution_count
290 # silent should force store_history=False
290 # silent should force store_history=False
291 ip.run_cell("1", store_history=True, silent=True)
291 ip.run_cell("1", store_history=True, silent=True)
292
292
293 self.assertEqual(ec, ip.execution_count)
293 self.assertEqual(ec, ip.execution_count)
294 # double-check that non-silent exec did what we expected
294 # double-check that non-silent exec did what we expected
295 # silent to avoid
295 # silent to avoid
296 ip.run_cell("1", store_history=True)
296 ip.run_cell("1", store_history=True)
297 self.assertEqual(ec+1, ip.execution_count)
297 self.assertEqual(ec+1, ip.execution_count)
298
298
299 def test_silent_nodisplayhook(self):
299 def test_silent_nodisplayhook(self):
300 """run_cell(silent=True) doesn't trigger displayhook"""
300 """run_cell(silent=True) doesn't trigger displayhook"""
301 d = dict(called=False)
301 d = dict(called=False)
302
302
303 trap = ip.display_trap
303 trap = ip.display_trap
304 save_hook = trap.hook
304 save_hook = trap.hook
305
305
306 def failing_hook(*args, **kwargs):
306 def failing_hook(*args, **kwargs):
307 d['called'] = True
307 d['called'] = True
308
308
309 try:
309 try:
310 trap.hook = failing_hook
310 trap.hook = failing_hook
311 ip.run_cell("1", silent=True)
311 ip.run_cell("1", silent=True)
312 self.assertFalse(d['called'])
312 self.assertFalse(d['called'])
313 # double-check that non-silent exec did what we expected
313 # double-check that non-silent exec did what we expected
314 # silent to avoid
314 # silent to avoid
315 ip.run_cell("1")
315 ip.run_cell("1")
316 self.assertTrue(d['called'])
316 self.assertTrue(d['called'])
317 finally:
317 finally:
318 trap.hook = save_hook
318 trap.hook = save_hook
319
319
320 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
320 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
321 def test_print_softspace(self):
321 def test_print_softspace(self):
322 """Verify that softspace is handled correctly when executing multiple
322 """Verify that softspace is handled correctly when executing multiple
323 statements.
323 statements.
324
324
325 In [1]: print 1; print 2
325 In [1]: print 1; print 2
326 1
326 1
327 2
327 2
328
328
329 In [2]: print 1,; print 2
329 In [2]: print 1,; print 2
330 1 2
330 1 2
331 """
331 """
332
332
333 def test_ofind_line_magic(self):
333 def test_ofind_line_magic(self):
334 from IPython.core.magic import register_line_magic
334 from IPython.core.magic import register_line_magic
335
335
336 @register_line_magic
336 @register_line_magic
337 def lmagic(line):
337 def lmagic(line):
338 "A line magic"
338 "A line magic"
339
339
340 # Get info on line magic
340 # Get info on line magic
341 lfind = ip._ofind('lmagic')
341 lfind = ip._ofind('lmagic')
342 info = dict(found=True, isalias=False, ismagic=True,
342 info = dict(found=True, isalias=False, ismagic=True,
343 namespace = 'IPython internal', obj= lmagic.__wrapped__,
343 namespace = 'IPython internal', obj= lmagic.__wrapped__,
344 parent = None)
344 parent = None)
345 nt.assert_equal(lfind, info)
345 nt.assert_equal(lfind, info)
346
346
347 def test_ofind_cell_magic(self):
347 def test_ofind_cell_magic(self):
348 from IPython.core.magic import register_cell_magic
348 from IPython.core.magic import register_cell_magic
349
349
350 @register_cell_magic
350 @register_cell_magic
351 def cmagic(line, cell):
351 def cmagic(line, cell):
352 "A cell magic"
352 "A cell magic"
353
353
354 # Get info on cell magic
354 # Get info on cell magic
355 find = ip._ofind('cmagic')
355 find = ip._ofind('cmagic')
356 info = dict(found=True, isalias=False, ismagic=True,
356 info = dict(found=True, isalias=False, ismagic=True,
357 namespace = 'IPython internal', obj= cmagic.__wrapped__,
357 namespace = 'IPython internal', obj= cmagic.__wrapped__,
358 parent = None)
358 parent = None)
359 nt.assert_equal(find, info)
359 nt.assert_equal(find, info)
360
360
361 def test_custom_exception(self):
361 def test_custom_exception(self):
362 called = []
362 called = []
363 def my_handler(shell, etype, value, tb, tb_offset=None):
363 def my_handler(shell, etype, value, tb, tb_offset=None):
364 called.append(etype)
364 called.append(etype)
365 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
365 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
366
366
367 ip.set_custom_exc((ValueError,), my_handler)
367 ip.set_custom_exc((ValueError,), my_handler)
368 try:
368 try:
369 ip.run_cell("raise ValueError('test')")
369 ip.run_cell("raise ValueError('test')")
370 # Check that this was called, and only once.
370 # Check that this was called, and only once.
371 self.assertEqual(called, [ValueError])
371 self.assertEqual(called, [ValueError])
372 finally:
372 finally:
373 # Reset the custom exception hook
373 # Reset the custom exception hook
374 ip.set_custom_exc((), None)
374 ip.set_custom_exc((), None)
375
375
376
376
377 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
377 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
378
378
379 def setUp(self):
379 def setUp(self):
380 self.BASETESTDIR = tempfile.mkdtemp()
380 self.BASETESTDIR = tempfile.mkdtemp()
381 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
381 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
382 os.mkdir(self.TESTDIR)
382 os.mkdir(self.TESTDIR)
383 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
383 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
384 sfile.write("pass\n")
384 sfile.write("pass\n")
385 self.oldpath = os.getcwdu()
385 self.oldpath = os.getcwdu()
386 os.chdir(self.TESTDIR)
386 os.chdir(self.TESTDIR)
387 self.fname = u"Γ₯Àâtestscript.py"
387 self.fname = u"Γ₯Àâtestscript.py"
388
388
389 def tearDown(self):
389 def tearDown(self):
390 os.chdir(self.oldpath)
390 os.chdir(self.oldpath)
391 shutil.rmtree(self.BASETESTDIR)
391 shutil.rmtree(self.BASETESTDIR)
392
392
393 def test_1(self):
393 def test_1(self):
394 """Test safe_execfile with non-ascii path
394 """Test safe_execfile with non-ascii path
395 """
395 """
396 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
396 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
397
397
398
398
399 class TestSystemRaw(unittest.TestCase):
399 class TestSystemRaw(unittest.TestCase):
400 def test_1(self):
400 def test_1(self):
401 """Test system_raw with non-ascii cmd
401 """Test system_raw with non-ascii cmd
402 """
402 """
403 cmd = ur'''python -c "'Γ₯Àâ'" '''
403 cmd = ur'''python -c "'Γ₯Àâ'" '''
404 ip.system_raw(cmd)
404 ip.system_raw(cmd)
405
405
406 class TestModules(unittest.TestCase, tt.TempFileMixin):
406 class TestModules(unittest.TestCase, tt.TempFileMixin):
407 def test_extraneous_loads(self):
407 def test_extraneous_loads(self):
408 """Test we're not loading modules on startup that we shouldn't.
408 """Test we're not loading modules on startup that we shouldn't.
409 """
409 """
410 self.mktmp("import sys\n"
410 self.mktmp("import sys\n"
411 "print('numpy' in sys.modules)\n"
411 "print('numpy' in sys.modules)\n"
412 "print('IPython.parallel' in sys.modules)\n"
412 "print('IPython.parallel' in sys.modules)\n"
413 "print('IPython.zmq' in sys.modules)\n"
413 "print('IPython.zmq' in sys.modules)\n"
414 )
414 )
415 out = "False\nFalse\nFalse\n"
415 out = "False\nFalse\nFalse\n"
416 tt.ipexec_validate(self.fname, out)
416 tt.ipexec_validate(self.fname, out)
417
417
418 class Negator(ast.NodeTransformer):
418 class Negator(ast.NodeTransformer):
419 """Negates all number literals in an AST."""
419 """Negates all number literals in an AST."""
420 def visit_Num(self, node):
420 def visit_Num(self, node):
421 node.n = -node.n
421 node.n = -node.n
422 return node
422 return node
423
423
424 class TestAstTransform(unittest.TestCase):
424 class TestAstTransform(unittest.TestCase):
425 def setUp(self):
425 def setUp(self):
426 self.negator = Negator()
426 self.negator = Negator()
427 ip.ast_transformers.append(self.negator)
427 ip.ast_transformers.append(self.negator)
428
428
429 def tearDown(self):
429 def tearDown(self):
430 ip.ast_transformers.remove(self.negator)
430 ip.ast_transformers.remove(self.negator)
431
431
432 def test_run_cell(self):
432 def test_run_cell(self):
433 with tt.AssertPrints('-34'):
433 with tt.AssertPrints('-34'):
434 ip.run_cell('print (12 + 22)')
434 ip.run_cell('print (12 + 22)')
435
435
436 # A named reference to a number shouldn't be transformed.
436 # A named reference to a number shouldn't be transformed.
437 ip.user_ns['n'] = 55
437 ip.user_ns['n'] = 55
438 with tt.AssertNotPrints('-55'):
438 with tt.AssertNotPrints('-55'):
439 ip.run_cell('print (n)')
439 ip.run_cell('print (n)')
440
440
441 def test_timeit(self):
441 def test_timeit(self):
442 called = set()
442 called = set()
443 def f(x):
443 def f(x):
444 called.add(x)
444 called.add(x)
445 ip.push({'f':f})
445 ip.push({'f':f})
446
446
447 with tt.AssertPrints("best of "):
447 with tt.AssertPrints("best of "):
448 ip.run_line_magic("timeit", "-n1 f(1)")
448 ip.run_line_magic("timeit", "-n1 f(1)")
449 self.assertEqual(called, set([-1]))
449 self.assertEqual(called, set([-1]))
450 called.clear()
450 called.clear()
451
451
452 with tt.AssertPrints("best of "):
452 with tt.AssertPrints("best of "):
453 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
453 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
454 self.assertEqual(called, set([-2, -3]))
454 self.assertEqual(called, set([-2, -3]))
455
455
456 def test_time(self):
456 def test_time(self):
457 called = []
457 called = []
458 def f(x):
458 def f(x):
459 called.append(x)
459 called.append(x)
460 ip.push({'f':f})
460 ip.push({'f':f})
461
461
462 # Test with an expression
462 # Test with an expression
463 with tt.AssertPrints("CPU times"):
463 with tt.AssertPrints("CPU times"):
464 ip.run_line_magic("time", "f(5+9)")
464 ip.run_line_magic("time", "f(5+9)")
465 self.assertEqual(called, [-14])
465 self.assertEqual(called, [-14])
466 called[:] = []
466 called[:] = []
467
467
468 # Test with a statement (different code path)
468 # Test with a statement (different code path)
469 with tt.AssertPrints("CPU times"):
469 with tt.AssertPrints("CPU times"):
470 ip.run_line_magic("time", "a = f(-3 + -2)")
470 ip.run_line_magic("time", "a = f(-3 + -2)")
471 self.assertEqual(called, [5])
471 self.assertEqual(called, [5])
472
473 def test_macro(self):
474 ip.push({'a':10})
475 # The AST transformation makes this do a+=-1
476 ip.define_macro("amacro", "a+=1\nprint(a)")
477
478 with tt.AssertPrints("9"):
479 ip.run_cell("amacro")
480 with tt.AssertPrints("8"):
481 ip.run_cell("amacro")
472
482
473 class IntegerWrapper(ast.NodeTransformer):
483 class IntegerWrapper(ast.NodeTransformer):
474 """Wraps all integers in a call to Integer()"""
484 """Wraps all integers in a call to Integer()"""
475 def visit_Num(self, node):
485 def visit_Num(self, node):
476 if isinstance(node.n, int):
486 if isinstance(node.n, int):
477 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
487 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
478 args=[node], keywords=[])
488 args=[node], keywords=[])
479
489
480 class TestAstTransform2(unittest.TestCase):
490 class TestAstTransform2(unittest.TestCase):
481 def setUp(self):
491 def setUp(self):
482 self.intwrapper = IntegerWrapper()
492 self.intwrapper = IntegerWrapper()
483 ip.ast_transformers.append(self.intwrapper)
493 ip.ast_transformers.append(self.intwrapper)
484
494
485 self.calls = []
495 self.calls = []
486 def Integer(*args):
496 def Integer(*args):
487 self.calls.append(args)
497 self.calls.append(args)
488 return args
498 return args
489 ip.push({"Integer": Integer})
499 ip.push({"Integer": Integer})
490
500
491 def tearDown(self):
501 def tearDown(self):
492 ip.ast_transformers.remove(self.intwrapper)
502 ip.ast_transformers.remove(self.intwrapper)
493 del ip.user_ns['Integer']
503 del ip.user_ns['Integer']
494
504
495 def test_run_cell(self):
505 def test_run_cell(self):
496 ip.run_cell("n = 2")
506 ip.run_cell("n = 2")
497 self.assertEqual(self.calls, [(2,)])
507 self.assertEqual(self.calls, [(2,)])
498
508
499 def test_timeit(self):
509 def test_timeit(self):
500 called = set()
510 called = set()
501 def f(x):
511 def f(x):
502 called.add(x)
512 called.add(x)
503 ip.push({'f':f})
513 ip.push({'f':f})
504
514
505 with tt.AssertPrints("best of "):
515 with tt.AssertPrints("best of "):
506 ip.run_line_magic("timeit", "-n1 f(1)")
516 ip.run_line_magic("timeit", "-n1 f(1)")
507 self.assertEqual(called, set([(1,)]))
517 self.assertEqual(called, set([(1,)]))
508 called.clear()
518 called.clear()
509
519
510 with tt.AssertPrints("best of "):
520 with tt.AssertPrints("best of "):
511 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
521 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
512 self.assertEqual(called, set([(2,), (3,)]))
522 self.assertEqual(called, set([(2,), (3,)]))
513
523
514 class ErrorTransformer(ast.NodeTransformer):
524 class ErrorTransformer(ast.NodeTransformer):
515 """Throws an error when it sees a number."""
525 """Throws an error when it sees a number."""
516 def visit_Num(self):
526 def visit_Num(self):
517 raise ValueError("test")
527 raise ValueError("test")
518
528
519 class TestAstTransformError(unittest.TestCase):
529 class TestAstTransformError(unittest.TestCase):
520 def test_unregistering(self):
530 def test_unregistering(self):
521 err_transformer = ErrorTransformer()
531 err_transformer = ErrorTransformer()
522 ip.ast_transformers.append(err_transformer)
532 ip.ast_transformers.append(err_transformer)
523
533
524 with tt.AssertPrints("unregister", channel='stderr'):
534 with tt.AssertPrints("unregister", channel='stderr'):
525 ip.run_cell("1 + 2")
535 ip.run_cell("1 + 2")
526
536
527 # This should have been removed.
537 # This should have been removed.
528 nt.assert_not_in(err_transformer, ip.ast_transformers)
538 nt.assert_not_in(err_transformer, ip.ast_transformers)
529
539
530 def test__IPYTHON__():
540 def test__IPYTHON__():
531 # This shouldn't raise a NameError, that's all
541 # This shouldn't raise a NameError, that's all
532 __IPYTHON__
542 __IPYTHON__
General Comments 0
You need to be logged in to leave comments. Login now