##// END OF EJS Templates
Add flush softspace test, i.e., print 1,; print 2
Bradley M. Froehle -
Show More
@@ -1,291 +1,304 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 os
23 import os
24 import shutil
24 import shutil
25 import tempfile
25 import tempfile
26 import unittest
26 import unittest
27 from os.path import join
27 from os.path import join
28 import sys
28 import sys
29 from StringIO import StringIO
29 from StringIO import StringIO
30
30
31 from IPython.testing.decorators import skipif
31 from IPython.utils import io
32 from IPython.utils import io
32
33
33 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
34 # Tests
35 # Tests
35 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
36
37
37 class InteractiveShellTestCase(unittest.TestCase):
38 class InteractiveShellTestCase(unittest.TestCase):
38 def test_naked_string_cells(self):
39 def test_naked_string_cells(self):
39 """Test that cells with only naked strings are fully executed"""
40 """Test that cells with only naked strings are fully executed"""
40 ip = get_ipython()
41 ip = get_ipython()
41 # First, single-line inputs
42 # First, single-line inputs
42 ip.run_cell('"a"\n')
43 ip.run_cell('"a"\n')
43 self.assertEquals(ip.user_ns['_'], 'a')
44 self.assertEquals(ip.user_ns['_'], 'a')
44 # And also multi-line cells
45 # And also multi-line cells
45 ip.run_cell('"""a\nb"""\n')
46 ip.run_cell('"""a\nb"""\n')
46 self.assertEquals(ip.user_ns['_'], 'a\nb')
47 self.assertEquals(ip.user_ns['_'], 'a\nb')
47
48
48 def test_run_empty_cell(self):
49 def test_run_empty_cell(self):
49 """Just make sure we don't get a horrible error with a blank
50 """Just make sure we don't get a horrible error with a blank
50 cell of input. Yes, I did overlook that."""
51 cell of input. Yes, I did overlook that."""
51 ip = get_ipython()
52 ip = get_ipython()
52 old_xc = ip.execution_count
53 old_xc = ip.execution_count
53 ip.run_cell('')
54 ip.run_cell('')
54 self.assertEquals(ip.execution_count, old_xc)
55 self.assertEquals(ip.execution_count, old_xc)
55
56
56 def test_run_cell_multiline(self):
57 def test_run_cell_multiline(self):
57 """Multi-block, multi-line cells must execute correctly.
58 """Multi-block, multi-line cells must execute correctly.
58 """
59 """
59 ip = get_ipython()
60 ip = get_ipython()
60 src = '\n'.join(["x=1",
61 src = '\n'.join(["x=1",
61 "y=2",
62 "y=2",
62 "if 1:",
63 "if 1:",
63 " x += 1",
64 " x += 1",
64 " y += 1",])
65 " y += 1",])
65 ip.run_cell(src)
66 ip.run_cell(src)
66 self.assertEquals(ip.user_ns['x'], 2)
67 self.assertEquals(ip.user_ns['x'], 2)
67 self.assertEquals(ip.user_ns['y'], 3)
68 self.assertEquals(ip.user_ns['y'], 3)
68
69
69 def test_multiline_string_cells(self):
70 def test_multiline_string_cells(self):
70 "Code sprinkled with multiline strings should execute (GH-306)"
71 "Code sprinkled with multiline strings should execute (GH-306)"
71 ip = get_ipython()
72 ip = get_ipython()
72 ip.run_cell('tmp=0')
73 ip.run_cell('tmp=0')
73 self.assertEquals(ip.user_ns['tmp'], 0)
74 self.assertEquals(ip.user_ns['tmp'], 0)
74 ip.run_cell('tmp=1;"""a\nb"""\n')
75 ip.run_cell('tmp=1;"""a\nb"""\n')
75 self.assertEquals(ip.user_ns['tmp'], 1)
76 self.assertEquals(ip.user_ns['tmp'], 1)
76
77
77 def test_dont_cache_with_semicolon(self):
78 def test_dont_cache_with_semicolon(self):
78 "Ending a line with semicolon should not cache the returned object (GH-307)"
79 "Ending a line with semicolon should not cache the returned object (GH-307)"
79 ip = get_ipython()
80 ip = get_ipython()
80 oldlen = len(ip.user_ns['Out'])
81 oldlen = len(ip.user_ns['Out'])
81 a = ip.run_cell('1;', store_history=True)
82 a = ip.run_cell('1;', store_history=True)
82 newlen = len(ip.user_ns['Out'])
83 newlen = len(ip.user_ns['Out'])
83 self.assertEquals(oldlen, newlen)
84 self.assertEquals(oldlen, newlen)
84 #also test the default caching behavior
85 #also test the default caching behavior
85 ip.run_cell('1', store_history=True)
86 ip.run_cell('1', store_history=True)
86 newlen = len(ip.user_ns['Out'])
87 newlen = len(ip.user_ns['Out'])
87 self.assertEquals(oldlen+1, newlen)
88 self.assertEquals(oldlen+1, newlen)
88
89
89 def test_In_variable(self):
90 def test_In_variable(self):
90 "Verify that In variable grows with user input (GH-284)"
91 "Verify that In variable grows with user input (GH-284)"
91 ip = get_ipython()
92 ip = get_ipython()
92 oldlen = len(ip.user_ns['In'])
93 oldlen = len(ip.user_ns['In'])
93 ip.run_cell('1;', store_history=True)
94 ip.run_cell('1;', store_history=True)
94 newlen = len(ip.user_ns['In'])
95 newlen = len(ip.user_ns['In'])
95 self.assertEquals(oldlen+1, newlen)
96 self.assertEquals(oldlen+1, newlen)
96 self.assertEquals(ip.user_ns['In'][-1],'1;')
97 self.assertEquals(ip.user_ns['In'][-1],'1;')
97
98
98 def test_magic_names_in_string(self):
99 def test_magic_names_in_string(self):
99 ip = get_ipython()
100 ip = get_ipython()
100 ip.run_cell('a = """\n%exit\n"""')
101 ip.run_cell('a = """\n%exit\n"""')
101 self.assertEquals(ip.user_ns['a'], '\n%exit\n')
102 self.assertEquals(ip.user_ns['a'], '\n%exit\n')
102
103
103 def test_alias_crash(self):
104 def test_alias_crash(self):
104 """Errors in prefilter can't crash IPython"""
105 """Errors in prefilter can't crash IPython"""
105 ip = get_ipython()
106 ip = get_ipython()
106 ip.run_cell('%alias parts echo first %s second %s')
107 ip.run_cell('%alias parts echo first %s second %s')
107 # capture stderr:
108 # capture stderr:
108 save_err = io.stderr
109 save_err = io.stderr
109 io.stderr = StringIO()
110 io.stderr = StringIO()
110 ip.run_cell('parts 1')
111 ip.run_cell('parts 1')
111 err = io.stderr.getvalue()
112 err = io.stderr.getvalue()
112 io.stderr = save_err
113 io.stderr = save_err
113 self.assertEquals(err.split(':')[0], 'ERROR')
114 self.assertEquals(err.split(':')[0], 'ERROR')
114
115
115 def test_trailing_newline(self):
116 def test_trailing_newline(self):
116 """test that running !(command) does not raise a SyntaxError"""
117 """test that running !(command) does not raise a SyntaxError"""
117 ip = get_ipython()
118 ip = get_ipython()
118 ip.run_cell('!(true)\n', False)
119 ip.run_cell('!(true)\n', False)
119 ip.run_cell('!(true)\n\n\n', False)
120 ip.run_cell('!(true)\n\n\n', False)
120
121
121 def test_gh_597(self):
122 def test_gh_597(self):
122 """Pretty-printing lists of objects with non-ascii reprs may cause
123 """Pretty-printing lists of objects with non-ascii reprs may cause
123 problems."""
124 problems."""
124 class Spam(object):
125 class Spam(object):
125 def __repr__(self):
126 def __repr__(self):
126 return "\xe9"*50
127 return "\xe9"*50
127 import IPython.core.formatters
128 import IPython.core.formatters
128 f = IPython.core.formatters.PlainTextFormatter()
129 f = IPython.core.formatters.PlainTextFormatter()
129 f([Spam(),Spam()])
130 f([Spam(),Spam()])
130
131
131
132
132 def test_future_flags(self):
133 def test_future_flags(self):
133 """Check that future flags are used for parsing code (gh-777)"""
134 """Check that future flags are used for parsing code (gh-777)"""
134 ip = get_ipython()
135 ip = get_ipython()
135 ip.run_cell('from __future__ import print_function')
136 ip.run_cell('from __future__ import print_function')
136 try:
137 try:
137 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
138 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
138 assert 'prfunc_return_val' in ip.user_ns
139 assert 'prfunc_return_val' in ip.user_ns
139 finally:
140 finally:
140 # Reset compiler flags so we don't mess up other tests.
141 # Reset compiler flags so we don't mess up other tests.
141 ip.compile.reset_compiler_flags()
142 ip.compile.reset_compiler_flags()
142
143
143 def test_future_unicode(self):
144 def test_future_unicode(self):
144 """Check that unicode_literals is imported from __future__ (gh #786)"""
145 """Check that unicode_literals is imported from __future__ (gh #786)"""
145 ip = get_ipython()
146 ip = get_ipython()
146 try:
147 try:
147 ip.run_cell(u'byte_str = "a"')
148 ip.run_cell(u'byte_str = "a"')
148 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
149 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
149 ip.run_cell('from __future__ import unicode_literals')
150 ip.run_cell('from __future__ import unicode_literals')
150 ip.run_cell(u'unicode_str = "a"')
151 ip.run_cell(u'unicode_str = "a"')
151 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
152 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
152 finally:
153 finally:
153 # Reset compiler flags so we don't mess up other tests.
154 # Reset compiler flags so we don't mess up other tests.
154 ip.compile.reset_compiler_flags()
155 ip.compile.reset_compiler_flags()
155
156
156 def test_can_pickle(self):
157 def test_can_pickle(self):
157 "Can we pickle objects defined interactively (GH-29)"
158 "Can we pickle objects defined interactively (GH-29)"
158 ip = get_ipython()
159 ip = get_ipython()
159 ip.reset()
160 ip.reset()
160 ip.run_cell(("class Mylist(list):\n"
161 ip.run_cell(("class Mylist(list):\n"
161 " def __init__(self,x=[]):\n"
162 " def __init__(self,x=[]):\n"
162 " list.__init__(self,x)"))
163 " list.__init__(self,x)"))
163 ip.run_cell("w=Mylist([1,2,3])")
164 ip.run_cell("w=Mylist([1,2,3])")
164
165
165 from cPickle import dumps
166 from cPickle import dumps
166
167
167 # We need to swap in our main module - this is only necessary
168 # We need to swap in our main module - this is only necessary
168 # inside the test framework, because IPython puts the interactive module
169 # inside the test framework, because IPython puts the interactive module
169 # in place (but the test framework undoes this).
170 # in place (but the test framework undoes this).
170 _main = sys.modules['__main__']
171 _main = sys.modules['__main__']
171 sys.modules['__main__'] = ip.user_module
172 sys.modules['__main__'] = ip.user_module
172 try:
173 try:
173 res = dumps(ip.user_ns["w"])
174 res = dumps(ip.user_ns["w"])
174 finally:
175 finally:
175 sys.modules['__main__'] = _main
176 sys.modules['__main__'] = _main
176 self.assertTrue(isinstance(res, bytes))
177 self.assertTrue(isinstance(res, bytes))
177
178
178 def test_global_ns(self):
179 def test_global_ns(self):
179 "Code in functions must be able to access variables outside them."
180 "Code in functions must be able to access variables outside them."
180 ip = get_ipython()
181 ip = get_ipython()
181 ip.run_cell("a = 10")
182 ip.run_cell("a = 10")
182 ip.run_cell(("def f(x):\n"
183 ip.run_cell(("def f(x):\n"
183 " return x + a"))
184 " return x + a"))
184 ip.run_cell("b = f(12)")
185 ip.run_cell("b = f(12)")
185 self.assertEqual(ip.user_ns["b"], 22)
186 self.assertEqual(ip.user_ns["b"], 22)
186
187
187 def test_bad_custom_tb(self):
188 def test_bad_custom_tb(self):
188 """Check that InteractiveShell is protected from bad custom exception handlers"""
189 """Check that InteractiveShell is protected from bad custom exception handlers"""
189 ip = get_ipython()
190 ip = get_ipython()
190 from IPython.utils import io
191 from IPython.utils import io
191 save_stderr = io.stderr
192 save_stderr = io.stderr
192 try:
193 try:
193 # capture stderr
194 # capture stderr
194 io.stderr = StringIO()
195 io.stderr = StringIO()
195 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
196 self.assertEquals(ip.custom_exceptions, (IOError,))
197 self.assertEquals(ip.custom_exceptions, (IOError,))
197 ip.run_cell(u'raise IOError("foo")')
198 ip.run_cell(u'raise IOError("foo")')
198 self.assertEquals(ip.custom_exceptions, ())
199 self.assertEquals(ip.custom_exceptions, ())
199 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
200 finally:
201 finally:
201 io.stderr = save_stderr
202 io.stderr = save_stderr
202
203
203 def test_bad_custom_tb_return(self):
204 def test_bad_custom_tb_return(self):
204 """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"""
205 ip = get_ipython()
206 ip = get_ipython()
206 from IPython.utils import io
207 from IPython.utils import io
207 save_stderr = io.stderr
208 save_stderr = io.stderr
208 try:
209 try:
209 # capture stderr
210 # capture stderr
210 io.stderr = StringIO()
211 io.stderr = StringIO()
211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 self.assertEquals(ip.custom_exceptions, (NameError,))
213 self.assertEquals(ip.custom_exceptions, (NameError,))
213 ip.run_cell(u'a=abracadabra')
214 ip.run_cell(u'a=abracadabra')
214 self.assertEquals(ip.custom_exceptions, ())
215 self.assertEquals(ip.custom_exceptions, ())
215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 finally:
217 finally:
217 io.stderr = save_stderr
218 io.stderr = save_stderr
218
219
219 def test_drop_by_id(self):
220 def test_drop_by_id(self):
220 ip = get_ipython()
221 ip = get_ipython()
221 myvars = {"a":object(), "b":object(), "c": object()}
222 myvars = {"a":object(), "b":object(), "c": object()}
222 ip.push(myvars, interactive=False)
223 ip.push(myvars, interactive=False)
223 for name in myvars:
224 for name in myvars:
224 assert name in ip.user_ns, name
225 assert name in ip.user_ns, name
225 assert name in ip.user_ns_hidden, name
226 assert name in ip.user_ns_hidden, name
226 ip.user_ns['b'] = 12
227 ip.user_ns['b'] = 12
227 ip.drop_by_id(myvars)
228 ip.drop_by_id(myvars)
228 for name in ["a", "c"]:
229 for name in ["a", "c"]:
229 assert name not in ip.user_ns, name
230 assert name not in ip.user_ns, name
230 assert name not in ip.user_ns_hidden, name
231 assert name not in ip.user_ns_hidden, name
231 assert ip.user_ns['b'] == 12
232 assert ip.user_ns['b'] == 12
232 ip.reset()
233 ip.reset()
233
234
234 def test_var_expand(self):
235 def test_var_expand(self):
235 ip = get_ipython()
236 ip = get_ipython()
236 ip.user_ns['f'] = u'Ca\xf1o'
237 ip.user_ns['f'] = u'Ca\xf1o'
237 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
238 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
238 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
239 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
239 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
240 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
240 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
241 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
241
242
242 ip.user_ns['f'] = b'Ca\xc3\xb1o'
243 ip.user_ns['f'] = b'Ca\xc3\xb1o'
243 # This should not raise any exception:
244 # This should not raise any exception:
244 ip.var_expand(u'echo $f')
245 ip.var_expand(u'echo $f')
245
246
246 def test_bad_var_expand(self):
247 def test_bad_var_expand(self):
247 """var_expand on invalid formats shouldn't raise"""
248 """var_expand on invalid formats shouldn't raise"""
248 ip = get_ipython()
249 ip = get_ipython()
249
250
250 # SyntaxError
251 # SyntaxError
251 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
252 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
252 # NameError
253 # NameError
253 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
254 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
254 # ZeroDivisionError
255 # ZeroDivisionError
255 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
256 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
256
257
258 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
259 def test_print_softspace(self):
260 """Verify that softspace is handled correctly when executing multiple
261 statements.
262
263 In [1]: print 1; print 2
264 1
265 2
266
267 In [2]: print 1,; print 2
268 1 2
269 """
257
270
258 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
271 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
259
272
260 def setUp(self):
273 def setUp(self):
261 self.BASETESTDIR = tempfile.mkdtemp()
274 self.BASETESTDIR = tempfile.mkdtemp()
262 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
275 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
263 os.mkdir(self.TESTDIR)
276 os.mkdir(self.TESTDIR)
264 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
277 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
265 sfile.write("pass\n")
278 sfile.write("pass\n")
266 self.oldpath = os.getcwdu()
279 self.oldpath = os.getcwdu()
267 os.chdir(self.TESTDIR)
280 os.chdir(self.TESTDIR)
268 self.fname = u"åäötestscript.py"
281 self.fname = u"åäötestscript.py"
269
282
270
283
271 def tearDown(self):
284 def tearDown(self):
272 os.chdir(self.oldpath)
285 os.chdir(self.oldpath)
273 shutil.rmtree(self.BASETESTDIR)
286 shutil.rmtree(self.BASETESTDIR)
274
287
275 def test_1(self):
288 def test_1(self):
276 """Test safe_execfile with non-ascii path
289 """Test safe_execfile with non-ascii path
277 """
290 """
278 _ip.shell.safe_execfile(self.fname, {}, raise_exceptions=True)
291 _ip.shell.safe_execfile(self.fname, {}, raise_exceptions=True)
279
292
280
293
281 class TestSystemRaw(unittest.TestCase):
294 class TestSystemRaw(unittest.TestCase):
282 def test_1(self):
295 def test_1(self):
283 """Test system_raw with non-ascii cmd
296 """Test system_raw with non-ascii cmd
284 """
297 """
285 cmd = ur'''python -c "'åäö'" '''
298 cmd = ur'''python -c "'åäö'" '''
286 _ip.shell.system_raw(cmd)
299 _ip.shell.system_raw(cmd)
287
300
288
301
289 def test__IPYTHON__():
302 def test__IPYTHON__():
290 # This shouldn't raise a NameError, that's all
303 # This shouldn't raise a NameError, that's all
291 __IPYTHON__
304 __IPYTHON__
General Comments 0
You need to be logged in to leave comments. Login now