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