##// END OF EJS Templates
Add failing test for issue gh-1878
Thomas Kluyver -
Show More
@@ -1,389 +1,397 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 def test_var_expand_local(self):
243 ip.run_cell('def test():\n'
244 ' lvar = "ttt"\n'
245 ' ret = !echo {lvar}\n'
246 ' return ret[0]\n')
247 res = ip.user_ns['test']()
248 nt.assert_in('ttt', res)
249
242 250 def test_bad_var_expand(self):
243 251 """var_expand on invalid formats shouldn't raise"""
244 252 # SyntaxError
245 253 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
246 254 # NameError
247 255 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
248 256 # ZeroDivisionError
249 257 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
250 258
251 259 def test_silent_nopostexec(self):
252 260 """run_cell(silent=True) doesn't invoke post-exec funcs"""
253 261 d = dict(called=False)
254 262 def set_called():
255 263 d['called'] = True
256 264
257 265 ip.register_post_execute(set_called)
258 266 ip.run_cell("1", silent=True)
259 267 self.assertFalse(d['called'])
260 268 # double-check that non-silent exec did what we expected
261 269 # silent to avoid
262 270 ip.run_cell("1")
263 271 self.assertTrue(d['called'])
264 272 # remove post-exec
265 273 ip._post_execute.pop(set_called)
266 274
267 275 def test_silent_noadvance(self):
268 276 """run_cell(silent=True) doesn't advance execution_count"""
269 277 ec = ip.execution_count
270 278 # silent should force store_history=False
271 279 ip.run_cell("1", store_history=True, silent=True)
272 280
273 281 self.assertEquals(ec, ip.execution_count)
274 282 # double-check that non-silent exec did what we expected
275 283 # silent to avoid
276 284 ip.run_cell("1", store_history=True)
277 285 self.assertEquals(ec+1, ip.execution_count)
278 286
279 287 def test_silent_nodisplayhook(self):
280 288 """run_cell(silent=True) doesn't trigger displayhook"""
281 289 d = dict(called=False)
282 290
283 291 trap = ip.display_trap
284 292 save_hook = trap.hook
285 293
286 294 def failing_hook(*args, **kwargs):
287 295 d['called'] = True
288 296
289 297 try:
290 298 trap.hook = failing_hook
291 299 ip.run_cell("1", silent=True)
292 300 self.assertFalse(d['called'])
293 301 # double-check that non-silent exec did what we expected
294 302 # silent to avoid
295 303 ip.run_cell("1")
296 304 self.assertTrue(d['called'])
297 305 finally:
298 306 trap.hook = save_hook
299 307
300 308 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
301 309 def test_print_softspace(self):
302 310 """Verify that softspace is handled correctly when executing multiple
303 311 statements.
304 312
305 313 In [1]: print 1; print 2
306 314 1
307 315 2
308 316
309 317 In [2]: print 1,; print 2
310 318 1 2
311 319 """
312 320
313 321 def test_ofind_line_magic(self):
314 322 from IPython.core.magic import register_line_magic
315 323
316 324 @register_line_magic
317 325 def lmagic(line):
318 326 "A line magic"
319 327
320 328 # Get info on line magic
321 329 lfind = ip._ofind('lmagic')
322 330 info = dict(found=True, isalias=False, ismagic=True,
323 331 namespace = 'IPython internal', obj= lmagic.__wrapped__,
324 332 parent = None)
325 333 nt.assert_equal(lfind, info)
326 334
327 335 def test_ofind_cell_magic(self):
328 336 from IPython.core.magic import register_cell_magic
329 337
330 338 @register_cell_magic
331 339 def cmagic(line, cell):
332 340 "A cell magic"
333 341
334 342 # Get info on cell magic
335 343 find = ip._ofind('cmagic')
336 344 info = dict(found=True, isalias=False, ismagic=True,
337 345 namespace = 'IPython internal', obj= cmagic.__wrapped__,
338 346 parent = None)
339 347 nt.assert_equal(find, info)
340 348
341 349 def test_custom_exception(self):
342 350 called = []
343 351 def my_handler(shell, etype, value, tb, tb_offset=None):
344 352 called.append(etype)
345 353 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
346 354
347 355 ip.set_custom_exc((ValueError,), my_handler)
348 356 try:
349 357 ip.run_cell("raise ValueError('test')")
350 358 # Check that this was called, and only once.
351 359 self.assertEqual(called, [ValueError])
352 360 finally:
353 361 # Reset the custom exception hook
354 362 ip.set_custom_exc((), None)
355 363
356 364
357 365 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
358 366
359 367 def setUp(self):
360 368 self.BASETESTDIR = tempfile.mkdtemp()
361 369 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
362 370 os.mkdir(self.TESTDIR)
363 371 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
364 372 sfile.write("pass\n")
365 373 self.oldpath = os.getcwdu()
366 374 os.chdir(self.TESTDIR)
367 375 self.fname = u"åäötestscript.py"
368 376
369 377 def tearDown(self):
370 378 os.chdir(self.oldpath)
371 379 shutil.rmtree(self.BASETESTDIR)
372 380
373 381 def test_1(self):
374 382 """Test safe_execfile with non-ascii path
375 383 """
376 384 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
377 385
378 386
379 387 class TestSystemRaw(unittest.TestCase):
380 388 def test_1(self):
381 389 """Test system_raw with non-ascii cmd
382 390 """
383 391 cmd = ur'''python -c "'åäö'" '''
384 392 ip.system_raw(cmd)
385 393
386 394
387 395 def test__IPYTHON__():
388 396 # This shouldn't raise a NameError, that's all
389 397 __IPYTHON__
General Comments 0
You need to be logged in to leave comments. Login now