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