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