##// END OF EJS Templates
Add test for alias creation, use and destruction
Thomas Kluyver -
Show More
@@ -0,0 +1,41 b''
1 from IPython.utils.capture import capture_output
2
3 import nose.tools as nt
4
5 def test_alias_lifecycle():
6 name = 'test_alias1'
7 cmd = 'echo "Hello"'
8 am = _ip.alias_manager
9 am.clear_aliases()
10 am.define_alias(name, cmd)
11 assert am.is_alias(name)
12 nt.assert_equal(am.retrieve_alias(name), cmd)
13 nt.assert_in((name, cmd), am.aliases)
14
15 # Test running the alias
16 orig_system = _ip.system
17 result = []
18 _ip.system = result.append
19 try:
20 _ip.run_cell('%{}'.format(name))
21 result = [c.strip() for c in result]
22 nt.assert_equal(result, [cmd])
23 finally:
24 _ip.system = orig_system
25
26 # Test removing the alias
27 am.undefine_alias(name)
28 assert not am.is_alias(name)
29 with nt.assert_raises(ValueError):
30 am.retrieve_alias(name)
31 nt.assert_not_in((name, cmd), am.aliases)
32
33
34 def test_alias_args_error():
35 """Error expanding with wrong number of arguments"""
36 _ip.alias_manager.define_alias('parts', 'echo first %s second %s')
37 # capture stderr:
38 with capture_output() as cap:
39 _ip.run_cell('parts 1')
40
41 nt.assert_equal(cap.stderr.split(':')[0], 'UsageError') No newline at end of file
@@ -1,652 +1,641 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 ast
23 import ast
24 import os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27 import tempfile
27 import tempfile
28 import unittest
28 import unittest
29 from os.path import join
29 from os.path import join
30 from StringIO import StringIO
30 from StringIO import StringIO
31
31
32 # third-party
32 # third-party
33 import nose.tools as nt
33 import nose.tools as nt
34
34
35 # Our own
35 # Our own
36 from IPython.testing.decorators import skipif, onlyif_unicode_paths
36 from IPython.testing.decorators import skipif, onlyif_unicode_paths
37 from IPython.testing import tools as tt
37 from IPython.testing import tools as tt
38 from IPython.utils import io
38 from IPython.utils import io
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Globals
41 # Globals
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # This is used by every single test, no point repeating it ad nauseam
43 # This is used by every single test, no point repeating it ad nauseam
44 ip = get_ipython()
44 ip = get_ipython()
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Tests
47 # Tests
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class InteractiveShellTestCase(unittest.TestCase):
50 class InteractiveShellTestCase(unittest.TestCase):
51 def test_naked_string_cells(self):
51 def test_naked_string_cells(self):
52 """Test that cells with only naked strings are fully executed"""
52 """Test that cells with only naked strings are fully executed"""
53 # First, single-line inputs
53 # First, single-line inputs
54 ip.run_cell('"a"\n')
54 ip.run_cell('"a"\n')
55 self.assertEqual(ip.user_ns['_'], 'a')
55 self.assertEqual(ip.user_ns['_'], 'a')
56 # And also multi-line cells
56 # And also multi-line cells
57 ip.run_cell('"""a\nb"""\n')
57 ip.run_cell('"""a\nb"""\n')
58 self.assertEqual(ip.user_ns['_'], 'a\nb')
58 self.assertEqual(ip.user_ns['_'], 'a\nb')
59
59
60 def test_run_empty_cell(self):
60 def test_run_empty_cell(self):
61 """Just make sure we don't get a horrible error with a blank
61 """Just make sure we don't get a horrible error with a blank
62 cell of input. Yes, I did overlook that."""
62 cell of input. Yes, I did overlook that."""
63 old_xc = ip.execution_count
63 old_xc = ip.execution_count
64 ip.run_cell('')
64 ip.run_cell('')
65 self.assertEqual(ip.execution_count, old_xc)
65 self.assertEqual(ip.execution_count, old_xc)
66
66
67 def test_run_cell_multiline(self):
67 def test_run_cell_multiline(self):
68 """Multi-block, multi-line cells must execute correctly.
68 """Multi-block, multi-line cells must execute correctly.
69 """
69 """
70 src = '\n'.join(["x=1",
70 src = '\n'.join(["x=1",
71 "y=2",
71 "y=2",
72 "if 1:",
72 "if 1:",
73 " x += 1",
73 " x += 1",
74 " y += 1",])
74 " y += 1",])
75 ip.run_cell(src)
75 ip.run_cell(src)
76 self.assertEqual(ip.user_ns['x'], 2)
76 self.assertEqual(ip.user_ns['x'], 2)
77 self.assertEqual(ip.user_ns['y'], 3)
77 self.assertEqual(ip.user_ns['y'], 3)
78
78
79 def test_multiline_string_cells(self):
79 def test_multiline_string_cells(self):
80 "Code sprinkled with multiline strings should execute (GH-306)"
80 "Code sprinkled with multiline strings should execute (GH-306)"
81 ip.run_cell('tmp=0')
81 ip.run_cell('tmp=0')
82 self.assertEqual(ip.user_ns['tmp'], 0)
82 self.assertEqual(ip.user_ns['tmp'], 0)
83 ip.run_cell('tmp=1;"""a\nb"""\n')
83 ip.run_cell('tmp=1;"""a\nb"""\n')
84 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(ip.user_ns['tmp'], 1)
85
85
86 def test_dont_cache_with_semicolon(self):
86 def test_dont_cache_with_semicolon(self):
87 "Ending a line with semicolon should not cache the returned object (GH-307)"
87 "Ending a line with semicolon should not cache the returned object (GH-307)"
88 oldlen = len(ip.user_ns['Out'])
88 oldlen = len(ip.user_ns['Out'])
89 a = ip.run_cell('1;', store_history=True)
89 a = ip.run_cell('1;', store_history=True)
90 newlen = len(ip.user_ns['Out'])
90 newlen = len(ip.user_ns['Out'])
91 self.assertEqual(oldlen, newlen)
91 self.assertEqual(oldlen, newlen)
92 #also test the default caching behavior
92 #also test the default caching behavior
93 ip.run_cell('1', store_history=True)
93 ip.run_cell('1', store_history=True)
94 newlen = len(ip.user_ns['Out'])
94 newlen = len(ip.user_ns['Out'])
95 self.assertEqual(oldlen+1, newlen)
95 self.assertEqual(oldlen+1, newlen)
96
96
97 def test_In_variable(self):
97 def test_In_variable(self):
98 "Verify that In variable grows with user input (GH-284)"
98 "Verify that In variable grows with user input (GH-284)"
99 oldlen = len(ip.user_ns['In'])
99 oldlen = len(ip.user_ns['In'])
100 ip.run_cell('1;', store_history=True)
100 ip.run_cell('1;', store_history=True)
101 newlen = len(ip.user_ns['In'])
101 newlen = len(ip.user_ns['In'])
102 self.assertEqual(oldlen+1, newlen)
102 self.assertEqual(oldlen+1, newlen)
103 self.assertEqual(ip.user_ns['In'][-1],'1;')
103 self.assertEqual(ip.user_ns['In'][-1],'1;')
104
104
105 def test_magic_names_in_string(self):
105 def test_magic_names_in_string(self):
106 ip.run_cell('a = """\n%exit\n"""')
106 ip.run_cell('a = """\n%exit\n"""')
107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
108
108
109 def test_alias_crash(self):
110 """Errors in prefilter can't crash IPython"""
111 ip.run_cell('%alias parts echo first %s second %s')
112 # capture stderr:
113 save_err = io.stderr
114 io.stderr = StringIO()
115 ip.run_cell('parts 1')
116 err = io.stderr.getvalue()
117 io.stderr = save_err
118 self.assertEqual(err.split(':')[0], 'ERROR')
119
120 def test_trailing_newline(self):
109 def test_trailing_newline(self):
121 """test that running !(command) does not raise a SyntaxError"""
110 """test that running !(command) does not raise a SyntaxError"""
122 ip.run_cell('!(true)\n', False)
111 ip.run_cell('!(true)\n', False)
123 ip.run_cell('!(true)\n\n\n', False)
112 ip.run_cell('!(true)\n\n\n', False)
124
113
125 def test_gh_597(self):
114 def test_gh_597(self):
126 """Pretty-printing lists of objects with non-ascii reprs may cause
115 """Pretty-printing lists of objects with non-ascii reprs may cause
127 problems."""
116 problems."""
128 class Spam(object):
117 class Spam(object):
129 def __repr__(self):
118 def __repr__(self):
130 return "\xe9"*50
119 return "\xe9"*50
131 import IPython.core.formatters
120 import IPython.core.formatters
132 f = IPython.core.formatters.PlainTextFormatter()
121 f = IPython.core.formatters.PlainTextFormatter()
133 f([Spam(),Spam()])
122 f([Spam(),Spam()])
134
123
135
124
136 def test_future_flags(self):
125 def test_future_flags(self):
137 """Check that future flags are used for parsing code (gh-777)"""
126 """Check that future flags are used for parsing code (gh-777)"""
138 ip.run_cell('from __future__ import print_function')
127 ip.run_cell('from __future__ import print_function')
139 try:
128 try:
140 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
129 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
141 assert 'prfunc_return_val' in ip.user_ns
130 assert 'prfunc_return_val' in ip.user_ns
142 finally:
131 finally:
143 # Reset compiler flags so we don't mess up other tests.
132 # Reset compiler flags so we don't mess up other tests.
144 ip.compile.reset_compiler_flags()
133 ip.compile.reset_compiler_flags()
145
134
146 def test_future_unicode(self):
135 def test_future_unicode(self):
147 """Check that unicode_literals is imported from __future__ (gh #786)"""
136 """Check that unicode_literals is imported from __future__ (gh #786)"""
148 try:
137 try:
149 ip.run_cell(u'byte_str = "a"')
138 ip.run_cell(u'byte_str = "a"')
150 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
139 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
151 ip.run_cell('from __future__ import unicode_literals')
140 ip.run_cell('from __future__ import unicode_literals')
152 ip.run_cell(u'unicode_str = "a"')
141 ip.run_cell(u'unicode_str = "a"')
153 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
142 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
154 finally:
143 finally:
155 # Reset compiler flags so we don't mess up other tests.
144 # Reset compiler flags so we don't mess up other tests.
156 ip.compile.reset_compiler_flags()
145 ip.compile.reset_compiler_flags()
157
146
158 def test_can_pickle(self):
147 def test_can_pickle(self):
159 "Can we pickle objects defined interactively (GH-29)"
148 "Can we pickle objects defined interactively (GH-29)"
160 ip = get_ipython()
149 ip = get_ipython()
161 ip.reset()
150 ip.reset()
162 ip.run_cell(("class Mylist(list):\n"
151 ip.run_cell(("class Mylist(list):\n"
163 " def __init__(self,x=[]):\n"
152 " def __init__(self,x=[]):\n"
164 " list.__init__(self,x)"))
153 " list.__init__(self,x)"))
165 ip.run_cell("w=Mylist([1,2,3])")
154 ip.run_cell("w=Mylist([1,2,3])")
166
155
167 from cPickle import dumps
156 from cPickle import dumps
168
157
169 # We need to swap in our main module - this is only necessary
158 # We need to swap in our main module - this is only necessary
170 # inside the test framework, because IPython puts the interactive module
159 # inside the test framework, because IPython puts the interactive module
171 # in place (but the test framework undoes this).
160 # in place (but the test framework undoes this).
172 _main = sys.modules['__main__']
161 _main = sys.modules['__main__']
173 sys.modules['__main__'] = ip.user_module
162 sys.modules['__main__'] = ip.user_module
174 try:
163 try:
175 res = dumps(ip.user_ns["w"])
164 res = dumps(ip.user_ns["w"])
176 finally:
165 finally:
177 sys.modules['__main__'] = _main
166 sys.modules['__main__'] = _main
178 self.assertTrue(isinstance(res, bytes))
167 self.assertTrue(isinstance(res, bytes))
179
168
180 def test_global_ns(self):
169 def test_global_ns(self):
181 "Code in functions must be able to access variables outside them."
170 "Code in functions must be able to access variables outside them."
182 ip = get_ipython()
171 ip = get_ipython()
183 ip.run_cell("a = 10")
172 ip.run_cell("a = 10")
184 ip.run_cell(("def f(x):\n"
173 ip.run_cell(("def f(x):\n"
185 " return x + a"))
174 " return x + a"))
186 ip.run_cell("b = f(12)")
175 ip.run_cell("b = f(12)")
187 self.assertEqual(ip.user_ns["b"], 22)
176 self.assertEqual(ip.user_ns["b"], 22)
188
177
189 def test_bad_custom_tb(self):
178 def test_bad_custom_tb(self):
190 """Check that InteractiveShell is protected from bad custom exception handlers"""
179 """Check that InteractiveShell is protected from bad custom exception handlers"""
191 from IPython.utils import io
180 from IPython.utils import io
192 save_stderr = io.stderr
181 save_stderr = io.stderr
193 try:
182 try:
194 # capture stderr
183 # capture stderr
195 io.stderr = StringIO()
184 io.stderr = StringIO()
196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
185 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
197 self.assertEqual(ip.custom_exceptions, (IOError,))
186 self.assertEqual(ip.custom_exceptions, (IOError,))
198 ip.run_cell(u'raise IOError("foo")')
187 ip.run_cell(u'raise IOError("foo")')
199 self.assertEqual(ip.custom_exceptions, ())
188 self.assertEqual(ip.custom_exceptions, ())
200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
189 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
201 finally:
190 finally:
202 io.stderr = save_stderr
191 io.stderr = save_stderr
203
192
204 def test_bad_custom_tb_return(self):
193 def test_bad_custom_tb_return(self):
205 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
194 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 from IPython.utils import io
195 from IPython.utils import io
207 save_stderr = io.stderr
196 save_stderr = io.stderr
208 try:
197 try:
209 # capture stderr
198 # capture stderr
210 io.stderr = StringIO()
199 io.stderr = StringIO()
211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
200 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 self.assertEqual(ip.custom_exceptions, (NameError,))
201 self.assertEqual(ip.custom_exceptions, (NameError,))
213 ip.run_cell(u'a=abracadabra')
202 ip.run_cell(u'a=abracadabra')
214 self.assertEqual(ip.custom_exceptions, ())
203 self.assertEqual(ip.custom_exceptions, ())
215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
204 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 finally:
205 finally:
217 io.stderr = save_stderr
206 io.stderr = save_stderr
218
207
219 def test_drop_by_id(self):
208 def test_drop_by_id(self):
220 myvars = {"a":object(), "b":object(), "c": object()}
209 myvars = {"a":object(), "b":object(), "c": object()}
221 ip.push(myvars, interactive=False)
210 ip.push(myvars, interactive=False)
222 for name in myvars:
211 for name in myvars:
223 assert name in ip.user_ns, name
212 assert name in ip.user_ns, name
224 assert name in ip.user_ns_hidden, name
213 assert name in ip.user_ns_hidden, name
225 ip.user_ns['b'] = 12
214 ip.user_ns['b'] = 12
226 ip.drop_by_id(myvars)
215 ip.drop_by_id(myvars)
227 for name in ["a", "c"]:
216 for name in ["a", "c"]:
228 assert name not in ip.user_ns, name
217 assert name not in ip.user_ns, name
229 assert name not in ip.user_ns_hidden, name
218 assert name not in ip.user_ns_hidden, name
230 assert ip.user_ns['b'] == 12
219 assert ip.user_ns['b'] == 12
231 ip.reset()
220 ip.reset()
232
221
233 def test_var_expand(self):
222 def test_var_expand(self):
234 ip.user_ns['f'] = u'Ca\xf1o'
223 ip.user_ns['f'] = u'Ca\xf1o'
235 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
224 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
236 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
225 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
237 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
226 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
238 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
227 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
239
228
240 ip.user_ns['f'] = b'Ca\xc3\xb1o'
229 ip.user_ns['f'] = b'Ca\xc3\xb1o'
241 # This should not raise any exception:
230 # This should not raise any exception:
242 ip.var_expand(u'echo $f')
231 ip.var_expand(u'echo $f')
243
232
244 def test_var_expand_local(self):
233 def test_var_expand_local(self):
245 """Test local variable expansion in !system and %magic calls"""
234 """Test local variable expansion in !system and %magic calls"""
246 # !system
235 # !system
247 ip.run_cell('def test():\n'
236 ip.run_cell('def test():\n'
248 ' lvar = "ttt"\n'
237 ' lvar = "ttt"\n'
249 ' ret = !echo {lvar}\n'
238 ' ret = !echo {lvar}\n'
250 ' return ret[0]\n')
239 ' return ret[0]\n')
251 res = ip.user_ns['test']()
240 res = ip.user_ns['test']()
252 nt.assert_in('ttt', res)
241 nt.assert_in('ttt', res)
253
242
254 # %magic
243 # %magic
255 ip.run_cell('def makemacro():\n'
244 ip.run_cell('def makemacro():\n'
256 ' macroname = "macro_var_expand_locals"\n'
245 ' macroname = "macro_var_expand_locals"\n'
257 ' %macro {macroname} codestr\n')
246 ' %macro {macroname} codestr\n')
258 ip.user_ns['codestr'] = "str(12)"
247 ip.user_ns['codestr'] = "str(12)"
259 ip.run_cell('makemacro()')
248 ip.run_cell('makemacro()')
260 nt.assert_in('macro_var_expand_locals', ip.user_ns)
249 nt.assert_in('macro_var_expand_locals', ip.user_ns)
261
250
262 def test_var_expand_self(self):
251 def test_var_expand_self(self):
263 """Test variable expansion with the name 'self', which was failing.
252 """Test variable expansion with the name 'self', which was failing.
264
253
265 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
254 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
266 """
255 """
267 ip.run_cell('class cTest:\n'
256 ip.run_cell('class cTest:\n'
268 ' classvar="see me"\n'
257 ' classvar="see me"\n'
269 ' def test(self):\n'
258 ' def test(self):\n'
270 ' res = !echo Variable: {self.classvar}\n'
259 ' res = !echo Variable: {self.classvar}\n'
271 ' return res[0]\n')
260 ' return res[0]\n')
272 nt.assert_in('see me', ip.user_ns['cTest']().test())
261 nt.assert_in('see me', ip.user_ns['cTest']().test())
273
262
274 def test_bad_var_expand(self):
263 def test_bad_var_expand(self):
275 """var_expand on invalid formats shouldn't raise"""
264 """var_expand on invalid formats shouldn't raise"""
276 # SyntaxError
265 # SyntaxError
277 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
266 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
278 # NameError
267 # NameError
279 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
268 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
280 # ZeroDivisionError
269 # ZeroDivisionError
281 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
270 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
282
271
283 def test_silent_nopostexec(self):
272 def test_silent_nopostexec(self):
284 """run_cell(silent=True) doesn't invoke post-exec funcs"""
273 """run_cell(silent=True) doesn't invoke post-exec funcs"""
285 d = dict(called=False)
274 d = dict(called=False)
286 def set_called():
275 def set_called():
287 d['called'] = True
276 d['called'] = True
288
277
289 ip.register_post_execute(set_called)
278 ip.register_post_execute(set_called)
290 ip.run_cell("1", silent=True)
279 ip.run_cell("1", silent=True)
291 self.assertFalse(d['called'])
280 self.assertFalse(d['called'])
292 # double-check that non-silent exec did what we expected
281 # double-check that non-silent exec did what we expected
293 # silent to avoid
282 # silent to avoid
294 ip.run_cell("1")
283 ip.run_cell("1")
295 self.assertTrue(d['called'])
284 self.assertTrue(d['called'])
296 # remove post-exec
285 # remove post-exec
297 ip._post_execute.pop(set_called)
286 ip._post_execute.pop(set_called)
298
287
299 def test_silent_noadvance(self):
288 def test_silent_noadvance(self):
300 """run_cell(silent=True) doesn't advance execution_count"""
289 """run_cell(silent=True) doesn't advance execution_count"""
301 ec = ip.execution_count
290 ec = ip.execution_count
302 # silent should force store_history=False
291 # silent should force store_history=False
303 ip.run_cell("1", store_history=True, silent=True)
292 ip.run_cell("1", store_history=True, silent=True)
304
293
305 self.assertEqual(ec, ip.execution_count)
294 self.assertEqual(ec, ip.execution_count)
306 # double-check that non-silent exec did what we expected
295 # double-check that non-silent exec did what we expected
307 # silent to avoid
296 # silent to avoid
308 ip.run_cell("1", store_history=True)
297 ip.run_cell("1", store_history=True)
309 self.assertEqual(ec+1, ip.execution_count)
298 self.assertEqual(ec+1, ip.execution_count)
310
299
311 def test_silent_nodisplayhook(self):
300 def test_silent_nodisplayhook(self):
312 """run_cell(silent=True) doesn't trigger displayhook"""
301 """run_cell(silent=True) doesn't trigger displayhook"""
313 d = dict(called=False)
302 d = dict(called=False)
314
303
315 trap = ip.display_trap
304 trap = ip.display_trap
316 save_hook = trap.hook
305 save_hook = trap.hook
317
306
318 def failing_hook(*args, **kwargs):
307 def failing_hook(*args, **kwargs):
319 d['called'] = True
308 d['called'] = True
320
309
321 try:
310 try:
322 trap.hook = failing_hook
311 trap.hook = failing_hook
323 ip.run_cell("1", silent=True)
312 ip.run_cell("1", silent=True)
324 self.assertFalse(d['called'])
313 self.assertFalse(d['called'])
325 # double-check that non-silent exec did what we expected
314 # double-check that non-silent exec did what we expected
326 # silent to avoid
315 # silent to avoid
327 ip.run_cell("1")
316 ip.run_cell("1")
328 self.assertTrue(d['called'])
317 self.assertTrue(d['called'])
329 finally:
318 finally:
330 trap.hook = save_hook
319 trap.hook = save_hook
331
320
332 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
321 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
333 def test_print_softspace(self):
322 def test_print_softspace(self):
334 """Verify that softspace is handled correctly when executing multiple
323 """Verify that softspace is handled correctly when executing multiple
335 statements.
324 statements.
336
325
337 In [1]: print 1; print 2
326 In [1]: print 1; print 2
338 1
327 1
339 2
328 2
340
329
341 In [2]: print 1,; print 2
330 In [2]: print 1,; print 2
342 1 2
331 1 2
343 """
332 """
344
333
345 def test_ofind_line_magic(self):
334 def test_ofind_line_magic(self):
346 from IPython.core.magic import register_line_magic
335 from IPython.core.magic import register_line_magic
347
336
348 @register_line_magic
337 @register_line_magic
349 def lmagic(line):
338 def lmagic(line):
350 "A line magic"
339 "A line magic"
351
340
352 # Get info on line magic
341 # Get info on line magic
353 lfind = ip._ofind('lmagic')
342 lfind = ip._ofind('lmagic')
354 info = dict(found=True, isalias=False, ismagic=True,
343 info = dict(found=True, isalias=False, ismagic=True,
355 namespace = 'IPython internal', obj= lmagic.__wrapped__,
344 namespace = 'IPython internal', obj= lmagic.__wrapped__,
356 parent = None)
345 parent = None)
357 nt.assert_equal(lfind, info)
346 nt.assert_equal(lfind, info)
358
347
359 def test_ofind_cell_magic(self):
348 def test_ofind_cell_magic(self):
360 from IPython.core.magic import register_cell_magic
349 from IPython.core.magic import register_cell_magic
361
350
362 @register_cell_magic
351 @register_cell_magic
363 def cmagic(line, cell):
352 def cmagic(line, cell):
364 "A cell magic"
353 "A cell magic"
365
354
366 # Get info on cell magic
355 # Get info on cell magic
367 find = ip._ofind('cmagic')
356 find = ip._ofind('cmagic')
368 info = dict(found=True, isalias=False, ismagic=True,
357 info = dict(found=True, isalias=False, ismagic=True,
369 namespace = 'IPython internal', obj= cmagic.__wrapped__,
358 namespace = 'IPython internal', obj= cmagic.__wrapped__,
370 parent = None)
359 parent = None)
371 nt.assert_equal(find, info)
360 nt.assert_equal(find, info)
372
361
373 def test_custom_exception(self):
362 def test_custom_exception(self):
374 called = []
363 called = []
375 def my_handler(shell, etype, value, tb, tb_offset=None):
364 def my_handler(shell, etype, value, tb, tb_offset=None):
376 called.append(etype)
365 called.append(etype)
377 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
366 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
378
367
379 ip.set_custom_exc((ValueError,), my_handler)
368 ip.set_custom_exc((ValueError,), my_handler)
380 try:
369 try:
381 ip.run_cell("raise ValueError('test')")
370 ip.run_cell("raise ValueError('test')")
382 # Check that this was called, and only once.
371 # Check that this was called, and only once.
383 self.assertEqual(called, [ValueError])
372 self.assertEqual(called, [ValueError])
384 finally:
373 finally:
385 # Reset the custom exception hook
374 # Reset the custom exception hook
386 ip.set_custom_exc((), None)
375 ip.set_custom_exc((), None)
387
376
388 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
377 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
389 def test_future_environment(self):
378 def test_future_environment(self):
390 "Can we run code with & without the shell's __future__ imports?"
379 "Can we run code with & without the shell's __future__ imports?"
391 ip.run_cell("from __future__ import division")
380 ip.run_cell("from __future__ import division")
392 ip.run_cell("a = 1/2", shell_futures=True)
381 ip.run_cell("a = 1/2", shell_futures=True)
393 self.assertEqual(ip.user_ns['a'], 0.5)
382 self.assertEqual(ip.user_ns['a'], 0.5)
394 ip.run_cell("b = 1/2", shell_futures=False)
383 ip.run_cell("b = 1/2", shell_futures=False)
395 self.assertEqual(ip.user_ns['b'], 0)
384 self.assertEqual(ip.user_ns['b'], 0)
396
385
397 ip.compile.reset_compiler_flags()
386 ip.compile.reset_compiler_flags()
398 # This shouldn't leak to the shell's compiler
387 # This shouldn't leak to the shell's compiler
399 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
388 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
400 self.assertEqual(ip.user_ns['c'], 0.5)
389 self.assertEqual(ip.user_ns['c'], 0.5)
401 ip.run_cell("d = 1/2", shell_futures=True)
390 ip.run_cell("d = 1/2", shell_futures=True)
402 self.assertEqual(ip.user_ns['d'], 0)
391 self.assertEqual(ip.user_ns['d'], 0)
403
392
404
393
405 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
394 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
406
395
407 @onlyif_unicode_paths
396 @onlyif_unicode_paths
408 def setUp(self):
397 def setUp(self):
409 self.BASETESTDIR = tempfile.mkdtemp()
398 self.BASETESTDIR = tempfile.mkdtemp()
410 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
399 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
411 os.mkdir(self.TESTDIR)
400 os.mkdir(self.TESTDIR)
412 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
401 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
413 sfile.write("pass\n")
402 sfile.write("pass\n")
414 self.oldpath = os.getcwdu()
403 self.oldpath = os.getcwdu()
415 os.chdir(self.TESTDIR)
404 os.chdir(self.TESTDIR)
416 self.fname = u"Γ₯Àâtestscript.py"
405 self.fname = u"Γ₯Àâtestscript.py"
417
406
418 def tearDown(self):
407 def tearDown(self):
419 os.chdir(self.oldpath)
408 os.chdir(self.oldpath)
420 shutil.rmtree(self.BASETESTDIR)
409 shutil.rmtree(self.BASETESTDIR)
421
410
422 @onlyif_unicode_paths
411 @onlyif_unicode_paths
423 def test_1(self):
412 def test_1(self):
424 """Test safe_execfile with non-ascii path
413 """Test safe_execfile with non-ascii path
425 """
414 """
426 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
415 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
427
416
428
417
429 class TestSystemRaw(unittest.TestCase):
418 class TestSystemRaw(unittest.TestCase):
430 @onlyif_unicode_paths
419 @onlyif_unicode_paths
431 def test_1(self):
420 def test_1(self):
432 """Test system_raw with non-ascii cmd
421 """Test system_raw with non-ascii cmd
433 """
422 """
434 cmd = ur'''python -c "'Γ₯Àâ'" '''
423 cmd = ur'''python -c "'Γ₯Àâ'" '''
435 ip.system_raw(cmd)
424 ip.system_raw(cmd)
436
425
437 def test_exit_code(self):
426 def test_exit_code(self):
438 """Test that the exit code is parsed correctly."""
427 """Test that the exit code is parsed correctly."""
439 ip.system_raw('exit 1')
428 ip.system_raw('exit 1')
440 self.assertEqual(ip.user_ns['_exit_code'], 1)
429 self.assertEqual(ip.user_ns['_exit_code'], 1)
441
430
442 class TestModules(unittest.TestCase, tt.TempFileMixin):
431 class TestModules(unittest.TestCase, tt.TempFileMixin):
443 def test_extraneous_loads(self):
432 def test_extraneous_loads(self):
444 """Test we're not loading modules on startup that we shouldn't.
433 """Test we're not loading modules on startup that we shouldn't.
445 """
434 """
446 self.mktmp("import sys\n"
435 self.mktmp("import sys\n"
447 "print('numpy' in sys.modules)\n"
436 "print('numpy' in sys.modules)\n"
448 "print('IPython.parallel' in sys.modules)\n"
437 "print('IPython.parallel' in sys.modules)\n"
449 "print('IPython.kernel.zmq' in sys.modules)\n"
438 "print('IPython.kernel.zmq' in sys.modules)\n"
450 )
439 )
451 out = "False\nFalse\nFalse\n"
440 out = "False\nFalse\nFalse\n"
452 tt.ipexec_validate(self.fname, out)
441 tt.ipexec_validate(self.fname, out)
453
442
454 class Negator(ast.NodeTransformer):
443 class Negator(ast.NodeTransformer):
455 """Negates all number literals in an AST."""
444 """Negates all number literals in an AST."""
456 def visit_Num(self, node):
445 def visit_Num(self, node):
457 node.n = -node.n
446 node.n = -node.n
458 return node
447 return node
459
448
460 class TestAstTransform(unittest.TestCase):
449 class TestAstTransform(unittest.TestCase):
461 def setUp(self):
450 def setUp(self):
462 self.negator = Negator()
451 self.negator = Negator()
463 ip.ast_transformers.append(self.negator)
452 ip.ast_transformers.append(self.negator)
464
453
465 def tearDown(self):
454 def tearDown(self):
466 ip.ast_transformers.remove(self.negator)
455 ip.ast_transformers.remove(self.negator)
467
456
468 def test_run_cell(self):
457 def test_run_cell(self):
469 with tt.AssertPrints('-34'):
458 with tt.AssertPrints('-34'):
470 ip.run_cell('print (12 + 22)')
459 ip.run_cell('print (12 + 22)')
471
460
472 # A named reference to a number shouldn't be transformed.
461 # A named reference to a number shouldn't be transformed.
473 ip.user_ns['n'] = 55
462 ip.user_ns['n'] = 55
474 with tt.AssertNotPrints('-55'):
463 with tt.AssertNotPrints('-55'):
475 ip.run_cell('print (n)')
464 ip.run_cell('print (n)')
476
465
477 def test_timeit(self):
466 def test_timeit(self):
478 called = set()
467 called = set()
479 def f(x):
468 def f(x):
480 called.add(x)
469 called.add(x)
481 ip.push({'f':f})
470 ip.push({'f':f})
482
471
483 with tt.AssertPrints("best of "):
472 with tt.AssertPrints("best of "):
484 ip.run_line_magic("timeit", "-n1 f(1)")
473 ip.run_line_magic("timeit", "-n1 f(1)")
485 self.assertEqual(called, set([-1]))
474 self.assertEqual(called, set([-1]))
486 called.clear()
475 called.clear()
487
476
488 with tt.AssertPrints("best of "):
477 with tt.AssertPrints("best of "):
489 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
478 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
490 self.assertEqual(called, set([-2, -3]))
479 self.assertEqual(called, set([-2, -3]))
491
480
492 def test_time(self):
481 def test_time(self):
493 called = []
482 called = []
494 def f(x):
483 def f(x):
495 called.append(x)
484 called.append(x)
496 ip.push({'f':f})
485 ip.push({'f':f})
497
486
498 # Test with an expression
487 # Test with an expression
499 with tt.AssertPrints("Wall time: "):
488 with tt.AssertPrints("Wall time: "):
500 ip.run_line_magic("time", "f(5+9)")
489 ip.run_line_magic("time", "f(5+9)")
501 self.assertEqual(called, [-14])
490 self.assertEqual(called, [-14])
502 called[:] = []
491 called[:] = []
503
492
504 # Test with a statement (different code path)
493 # Test with a statement (different code path)
505 with tt.AssertPrints("Wall time: "):
494 with tt.AssertPrints("Wall time: "):
506 ip.run_line_magic("time", "a = f(-3 + -2)")
495 ip.run_line_magic("time", "a = f(-3 + -2)")
507 self.assertEqual(called, [5])
496 self.assertEqual(called, [5])
508
497
509 def test_macro(self):
498 def test_macro(self):
510 ip.push({'a':10})
499 ip.push({'a':10})
511 # The AST transformation makes this do a+=-1
500 # The AST transformation makes this do a+=-1
512 ip.define_macro("amacro", "a+=1\nprint(a)")
501 ip.define_macro("amacro", "a+=1\nprint(a)")
513
502
514 with tt.AssertPrints("9"):
503 with tt.AssertPrints("9"):
515 ip.run_cell("amacro")
504 ip.run_cell("amacro")
516 with tt.AssertPrints("8"):
505 with tt.AssertPrints("8"):
517 ip.run_cell("amacro")
506 ip.run_cell("amacro")
518
507
519 class IntegerWrapper(ast.NodeTransformer):
508 class IntegerWrapper(ast.NodeTransformer):
520 """Wraps all integers in a call to Integer()"""
509 """Wraps all integers in a call to Integer()"""
521 def visit_Num(self, node):
510 def visit_Num(self, node):
522 if isinstance(node.n, int):
511 if isinstance(node.n, int):
523 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
512 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
524 args=[node], keywords=[])
513 args=[node], keywords=[])
525 return node
514 return node
526
515
527 class TestAstTransform2(unittest.TestCase):
516 class TestAstTransform2(unittest.TestCase):
528 def setUp(self):
517 def setUp(self):
529 self.intwrapper = IntegerWrapper()
518 self.intwrapper = IntegerWrapper()
530 ip.ast_transformers.append(self.intwrapper)
519 ip.ast_transformers.append(self.intwrapper)
531
520
532 self.calls = []
521 self.calls = []
533 def Integer(*args):
522 def Integer(*args):
534 self.calls.append(args)
523 self.calls.append(args)
535 return args
524 return args
536 ip.push({"Integer": Integer})
525 ip.push({"Integer": Integer})
537
526
538 def tearDown(self):
527 def tearDown(self):
539 ip.ast_transformers.remove(self.intwrapper)
528 ip.ast_transformers.remove(self.intwrapper)
540 del ip.user_ns['Integer']
529 del ip.user_ns['Integer']
541
530
542 def test_run_cell(self):
531 def test_run_cell(self):
543 ip.run_cell("n = 2")
532 ip.run_cell("n = 2")
544 self.assertEqual(self.calls, [(2,)])
533 self.assertEqual(self.calls, [(2,)])
545
534
546 # This shouldn't throw an error
535 # This shouldn't throw an error
547 ip.run_cell("o = 2.0")
536 ip.run_cell("o = 2.0")
548 self.assertEqual(ip.user_ns['o'], 2.0)
537 self.assertEqual(ip.user_ns['o'], 2.0)
549
538
550 def test_timeit(self):
539 def test_timeit(self):
551 called = set()
540 called = set()
552 def f(x):
541 def f(x):
553 called.add(x)
542 called.add(x)
554 ip.push({'f':f})
543 ip.push({'f':f})
555
544
556 with tt.AssertPrints("best of "):
545 with tt.AssertPrints("best of "):
557 ip.run_line_magic("timeit", "-n1 f(1)")
546 ip.run_line_magic("timeit", "-n1 f(1)")
558 self.assertEqual(called, set([(1,)]))
547 self.assertEqual(called, set([(1,)]))
559 called.clear()
548 called.clear()
560
549
561 with tt.AssertPrints("best of "):
550 with tt.AssertPrints("best of "):
562 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
551 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
563 self.assertEqual(called, set([(2,), (3,)]))
552 self.assertEqual(called, set([(2,), (3,)]))
564
553
565 class ErrorTransformer(ast.NodeTransformer):
554 class ErrorTransformer(ast.NodeTransformer):
566 """Throws an error when it sees a number."""
555 """Throws an error when it sees a number."""
567 def visit_Num(self):
556 def visit_Num(self):
568 raise ValueError("test")
557 raise ValueError("test")
569
558
570 class TestAstTransformError(unittest.TestCase):
559 class TestAstTransformError(unittest.TestCase):
571 def test_unregistering(self):
560 def test_unregistering(self):
572 err_transformer = ErrorTransformer()
561 err_transformer = ErrorTransformer()
573 ip.ast_transformers.append(err_transformer)
562 ip.ast_transformers.append(err_transformer)
574
563
575 with tt.AssertPrints("unregister", channel='stderr'):
564 with tt.AssertPrints("unregister", channel='stderr'):
576 ip.run_cell("1 + 2")
565 ip.run_cell("1 + 2")
577
566
578 # This should have been removed.
567 # This should have been removed.
579 nt.assert_not_in(err_transformer, ip.ast_transformers)
568 nt.assert_not_in(err_transformer, ip.ast_transformers)
580
569
581 def test__IPYTHON__():
570 def test__IPYTHON__():
582 # This shouldn't raise a NameError, that's all
571 # This shouldn't raise a NameError, that's all
583 __IPYTHON__
572 __IPYTHON__
584
573
585
574
586 class DummyRepr(object):
575 class DummyRepr(object):
587 def __repr__(self):
576 def __repr__(self):
588 return "DummyRepr"
577 return "DummyRepr"
589
578
590 def _repr_html_(self):
579 def _repr_html_(self):
591 return "<b>dummy</b>"
580 return "<b>dummy</b>"
592
581
593 def _repr_javascript_(self):
582 def _repr_javascript_(self):
594 return "console.log('hi');", {'key': 'value'}
583 return "console.log('hi');", {'key': 'value'}
595
584
596
585
597 def test_user_variables():
586 def test_user_variables():
598 # enable all formatters
587 # enable all formatters
599 ip.display_formatter.active_types = ip.display_formatter.format_types
588 ip.display_formatter.active_types = ip.display_formatter.format_types
600
589
601 ip.user_ns['dummy'] = d = DummyRepr()
590 ip.user_ns['dummy'] = d = DummyRepr()
602 keys = set(['dummy', 'doesnotexist'])
591 keys = set(['dummy', 'doesnotexist'])
603 r = ip.user_variables(keys)
592 r = ip.user_variables(keys)
604
593
605 nt.assert_equal(keys, set(r.keys()))
594 nt.assert_equal(keys, set(r.keys()))
606 dummy = r['dummy']
595 dummy = r['dummy']
607 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
596 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
608 nt.assert_equal(dummy['status'], 'ok')
597 nt.assert_equal(dummy['status'], 'ok')
609 data = dummy['data']
598 data = dummy['data']
610 metadata = dummy['metadata']
599 metadata = dummy['metadata']
611 nt.assert_equal(data.get('text/html'), d._repr_html_())
600 nt.assert_equal(data.get('text/html'), d._repr_html_())
612 js, jsmd = d._repr_javascript_()
601 js, jsmd = d._repr_javascript_()
613 nt.assert_equal(data.get('application/javascript'), js)
602 nt.assert_equal(data.get('application/javascript'), js)
614 nt.assert_equal(metadata.get('application/javascript'), jsmd)
603 nt.assert_equal(metadata.get('application/javascript'), jsmd)
615
604
616 dne = r['doesnotexist']
605 dne = r['doesnotexist']
617 nt.assert_equal(dne['status'], 'error')
606 nt.assert_equal(dne['status'], 'error')
618 nt.assert_equal(dne['ename'], 'KeyError')
607 nt.assert_equal(dne['ename'], 'KeyError')
619
608
620 # back to text only
609 # back to text only
621 ip.display_formatter.active_types = ['text/plain']
610 ip.display_formatter.active_types = ['text/plain']
622
611
623 def test_user_expression():
612 def test_user_expression():
624 # enable all formatters
613 # enable all formatters
625 ip.display_formatter.active_types = ip.display_formatter.format_types
614 ip.display_formatter.active_types = ip.display_formatter.format_types
626 query = {
615 query = {
627 'a' : '1 + 2',
616 'a' : '1 + 2',
628 'b' : '1/0',
617 'b' : '1/0',
629 }
618 }
630 r = ip.user_expressions(query)
619 r = ip.user_expressions(query)
631 import pprint
620 import pprint
632 pprint.pprint(r)
621 pprint.pprint(r)
633 nt.assert_equal(r.keys(), query.keys())
622 nt.assert_equal(r.keys(), query.keys())
634 a = r['a']
623 a = r['a']
635 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
624 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
636 nt.assert_equal(a['status'], 'ok')
625 nt.assert_equal(a['status'], 'ok')
637 data = a['data']
626 data = a['data']
638 metadata = a['metadata']
627 metadata = a['metadata']
639 nt.assert_equal(data.get('text/plain'), '3')
628 nt.assert_equal(data.get('text/plain'), '3')
640
629
641 b = r['b']
630 b = r['b']
642 nt.assert_equal(b['status'], 'error')
631 nt.assert_equal(b['status'], 'error')
643 nt.assert_equal(b['ename'], 'ZeroDivisionError')
632 nt.assert_equal(b['ename'], 'ZeroDivisionError')
644
633
645 # back to text only
634 # back to text only
646 ip.display_formatter.active_types = ['text/plain']
635 ip.display_formatter.active_types = ['text/plain']
647
636
648
637
649
638
650
639
651
640
652
641
General Comments 0
You need to be logged in to leave comments. Login now