##// END OF EJS Templates
Fix various tests in IPython.core for Python 3.
Thomas Kluyver -
Show More
@@ -1,43 +1,45 b''
1 1 """These kinds of tests are less than ideal, but at least they run.
2 2
3 3 This was an old test that was being run interactively in the top-level tests/
4 4 directory, which we are removing. For now putting this here ensures at least
5 5 we do run the test, though ultimately this functionality should all be tested
6 6 with better-isolated tests that don't rely on the global instance in iptest.
7 7 """
8 from IPython.utils import py3compat
8 9
10 @py3compat.doctest_refactor_print
9 11 def doctest_autocall():
10 12 """
11 13 In [1]: def f1(a,b,c):
12 14 ...: return a+b+c
13 15 ...:
14 16
15 17 In [2]: def f2(a):
16 18 ...: return a + a
17 19 ...:
18 20
19 21 In [3]: ;f2 a b c
20 22 Out[3]: 'a b ca b c'
21 23
22 24 In [4]: assert _ == "a b ca b c"
23 25
24 26 In [5]: ,f1 a b c
25 27 Out[5]: 'abc'
26 28
27 29 In [6]: assert _ == 'abc'
28 30
29 31 In [7]: print _
30 32 abc
31 33
32 34 In [8]: /f1 1,2,3
33 35 Out[8]: 6
34 36
35 37 In [9]: assert _ == 6
36 38
37 39 In [10]: /f2 4
38 40 Out[10]: 8
39 41
40 42 In [11]: assert _ == 8
41 43
42 44 In [11]: del f1, f2
43 45 """
@@ -1,165 +1,167 b''
1 1 """Tests for input handlers.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # third party
8 8 import nose.tools as nt
9 9
10 10 # our own packages
11 11 from IPython.core import autocall
12 12 from IPython.testing import decorators as dec
13 13 from IPython.testing import tools as tt
14 14 from IPython.testing.globalipapp import get_ipython
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Globals
18 18 #-----------------------------------------------------------------------------
19 19
20 20 # Get the public instance of IPython
21 21 ip = get_ipython()
22 22
23 23 failures = []
24 24 num_tests = 0
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Test functions
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class CallableIndexable(object):
31 31 def __getitem__(self, idx): return True
32 32 def __call__(self, *args, **kws): return True
33 33
34 34
35 35 class Autocallable(autocall.IPyAutocall):
36 36 def __call__(self):
37 37 return "called"
38 38
39 39
40 40 def run(tests):
41 41 """Loop through a list of (pre, post) inputs, where pre is the string
42 42 handed to ipython, and post is how that string looks after it's been
43 43 transformed (i.e. ipython's notion of _i)"""
44 44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
45 45
46 46
47 47 def test_handlers():
48 48 # alias expansion
49 49
50 50 # We're using 'true' as our syscall of choice because it doesn't
51 51 # write anything to stdout.
52 52
53 53 # Turn off actual execution of aliases, because it's noisy
54 54 old_system_cmd = ip.system
55 55 ip.system = lambda cmd: None
56 56
57 57
58 58 ip.alias_manager.alias_table['an_alias'] = (0, 'true')
59 59 # These are useful for checking a particular recursive alias issue
60 60 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
61 61 ip.alias_manager.alias_table['d'] = (0, 'true')
62 run([("an_alias", 'get_ipython().system(u"true ")'), # alias
62 run([(i,py3compat.u_format(o)) for i,o in \
63 [("an_alias", 'get_ipython().system({u}"true ")'), # alias
63 64 # Below: recursive aliases should expand whitespace-surrounded
64 65 # chars, *not* initial chars which happen to be aliases:
65 ("top", 'get_ipython().system(u"d:/cygwin/top ")'),
66 ])
66 ("top", 'get_ipython().system({u}"d:/cygwin/top ")'),
67 ]])
67 68 ip.system = old_system_cmd
68 69
69 70 call_idx = CallableIndexable()
70 71 ip.user_ns['call_idx'] = call_idx
71 72
72 73 # For many of the below, we're also checking that leading whitespace
73 74 # turns off the esc char, which it should unless there is a continuation
74 75 # line.
75 run([('"no change"', '"no change"'), # normal
76 ("!true", 'get_ipython().system(u"true")'), # shell_escapes
77 ("!! true", 'get_ipython().magic(u"sx true")'), # shell_escapes + magic
78 ("!!true", 'get_ipython().magic(u"sx true")'), # shell_escapes + magic
79 ("%lsmagic", 'get_ipython().magic(u"lsmagic ")'), # magic
80 ("lsmagic", 'get_ipython().magic(u"lsmagic ")'), # magic
76 run([(i,py3compat.u_format(o)) for i,o in \
77 [('"no change"', '"no change"'), # normal
78 ("!true", 'get_ipython().system({u}"true")'), # shell_escapes
79 ("!! true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
80 ("!!true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
81 ("%lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
82 ("lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
81 83 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
82 84
83 85 # post-esc-char whitespace goes inside
84 ("! true", 'get_ipython().system(u" true")'),
86 ("! true", 'get_ipython().system({u}" true")'),
85 87
86 88 # handle_help
87 89
88 90 # These are weak tests -- just looking at what the help handlers
89 91 # logs, which is not how it really does its work. But it still
90 92 # lets us check the key paths through the handler.
91 93
92 94 ("x=1 # what?", "x=1 # what?"), # no help if valid python
93 ])
95 ]])
94 96
95 97 # multi_line_specials
96 98 ip.prefilter_manager.multi_line_specials = False
97 99 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
98 100 run([
99 101 ('if 1:\n !true', 'if 1:\n !true'),
100 102 ('if 1:\n lsmagic', 'if 1:\n lsmagic'),
101 103 ('if 1:\n an_alias', 'if 1:\n an_alias'),
102 104 ])
103 105
104 106 ip.prefilter_manager.multi_line_specials = True
105 107 # initial indents must be preserved.
106 run([
107 ('if 1:\n !true', 'if 1:\n get_ipython().system(u"true")'),
108 ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic(u"lsmagic ")'),
109 ('if 1:\n an_alias', 'if 1:\n get_ipython().system(u"true ")'),
108 run([(i,py3compat.u_format(o)) for i,o in \
109 [('if 1:\n !true', 'if 1:\n get_ipython().system({u}"true")'),
110 ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic({u}"lsmagic ")'),
111 ('if 1:\n an_alias', 'if 1:\n get_ipython().system({u}"true ")'),
110 112 # Weird one
111 ('if 1:\n !!true', 'if 1:\n get_ipython().magic(u"sx true")'),
113 ('if 1:\n !!true', 'if 1:\n get_ipython().magic({u}"sx true")'),
112 114
113 115 # Even with m_l_s on, autocall is off even with special chars
114 116 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
115 117 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
116 118 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
117 119 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
118 120 # What about !!
119 ])
121 ]])
120 122
121 123 # Objects which are instances of IPyAutocall are *always* autocalled
122 124 autocallable = Autocallable()
123 125 ip.user_ns['autocallable'] = autocallable
124 126
125 127 # auto
126 128 ip.magic('autocall 0')
127 129 # Only explicit escapes or instances of IPyAutocallable should get
128 130 # expanded
129 131 run([
130 132 ('len "abc"', 'len "abc"'),
131 133 ('autocallable', 'autocallable()'),
132 134 (",list 1 2 3", 'list("1", "2", "3")'),
133 135 (";list 1 2 3", 'list("1 2 3")'),
134 136 ("/len range(1,4)", 'len(range(1,4))'),
135 137 ])
136 138 ip.magic('autocall 1')
137 139 run([
138 140 (",list 1 2 3", 'list("1", "2", "3")'),
139 141 (";list 1 2 3", 'list("1 2 3")'),
140 142 ("/len range(1,4)", 'len(range(1,4))'),
141 143 ('len "abc"', 'len("abc")'),
142 144 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
143 145 # Autocall is turned off if first arg is [] and the object
144 146 # is both callable and indexable. Like so:
145 147 ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
146 148 ('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
147 149 ('call_idx 1', 'call_idx(1)'),
148 150 ('len', 'len '), # only at 2 does it auto-call on single args
149 151 ])
150 152 ip.magic('autocall 2')
151 153 run([
152 154 (",list 1 2 3", 'list("1", "2", "3")'),
153 155 (";list 1 2 3", 'list("1 2 3")'),
154 156 ("/len range(1,4)", 'len(range(1,4))'),
155 157 ('len "abc"', 'len("abc")'),
156 158 ('len "abc";', 'len("abc");'),
157 159 ('len [1,2]', 'len([1,2])'),
158 160 ('call_idx [1]', 'call_idx [1]'),
159 161 ('call_idx 1', 'call_idx(1)'),
160 162 # This is what's different:
161 163 ('len', 'len()'), # only at 2 does it auto-call on single args
162 164 ])
163 165 ip.magic('autocall 1')
164 166
165 167 nt.assert_equals(failures, [])
@@ -1,690 +1,698 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module.
3 3
4 4 Authors
5 5 -------
6 6 * Fernando Perez
7 7 * Robert Kern
8 8 """
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2010 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19 # stdlib
20 20 import unittest
21 21 import sys
22 22
23 23 # Third party
24 24 import nose.tools as nt
25 25
26 26 # Our own
27 27 from IPython.core import inputsplitter as isp
28 28 from IPython.testing import tools as tt
29 from IPython.utils import py3compat
29 30
30 31 #-----------------------------------------------------------------------------
31 32 # Semi-complete examples (also used as tests)
32 33 #-----------------------------------------------------------------------------
33 34
34 35 # Note: at the bottom, there's a slightly more complete version of this that
35 36 # can be useful during development of code here.
36 37
37 38 def mini_interactive_loop(input_func):
38 39 """Minimal example of the logic of an interactive interpreter loop.
39 40
40 41 This serves as an example, and it is used by the test system with a fake
41 42 raw_input that simulates interactive input."""
42 43
43 44 from IPython.core.inputsplitter import InputSplitter
44 45
45 46 isp = InputSplitter()
46 47 # In practice, this input loop would be wrapped in an outside loop to read
47 48 # input indefinitely, until some exit/quit command was issued. Here we
48 49 # only illustrate the basic inner loop.
49 50 while isp.push_accepts_more():
50 51 indent = ' '*isp.indent_spaces
51 52 prompt = '>>> ' + indent
52 53 line = indent + input_func(prompt)
53 54 isp.push(line)
54 55
55 56 # Here we just return input so we can use it in a test suite, but a real
56 57 # interpreter would instead send it for execution somewhere.
57 58 src = isp.source_reset()
58 59 #print 'Input source was:\n', src # dbg
59 60 return src
60 61
61 62 #-----------------------------------------------------------------------------
62 63 # Test utilities, just for local use
63 64 #-----------------------------------------------------------------------------
64 65
65 66 def assemble(block):
66 67 """Assemble a block into multi-line sub-blocks."""
67 68 return ['\n'.join(sub_block)+'\n' for sub_block in block]
68 69
69 70
70 71 def pseudo_input(lines):
71 72 """Return a function that acts like raw_input but feeds the input list."""
72 73 ilines = iter(lines)
73 74 def raw_in(prompt):
74 75 try:
75 76 return next(ilines)
76 77 except StopIteration:
77 78 return ''
78 79 return raw_in
79 80
80 81 #-----------------------------------------------------------------------------
81 82 # Tests
82 83 #-----------------------------------------------------------------------------
83 84 def test_spaces():
84 85 tests = [('', 0),
85 86 (' ', 1),
86 87 ('\n', 0),
87 88 (' \n', 1),
88 89 ('x', 0),
89 90 (' x', 1),
90 91 (' x',2),
91 92 (' x',4),
92 93 # Note: tabs are counted as a single whitespace!
93 94 ('\tx', 1),
94 95 ('\t x', 2),
95 96 ]
96 97 tt.check_pairs(isp.num_ini_spaces, tests)
97 98
98 99
99 100 def test_remove_comments():
100 101 tests = [('text', 'text'),
101 102 ('text # comment', 'text '),
102 103 ('text # comment\n', 'text \n'),
103 104 ('text # comment \n', 'text \n'),
104 105 ('line # c \nline\n','line \nline\n'),
105 106 ('line # c \nline#c2 \nline\nline #c\n\n',
106 107 'line \nline\nline\nline \n\n'),
107 108 ]
108 109 tt.check_pairs(isp.remove_comments, tests)
109 110
110 111 def test_has_comment():
111 112 tests = [('text', False),
112 113 ('text #comment', True),
113 114 ('text #comment\n', True),
114 115 ('#comment', True),
115 116 ('#comment\n', True),
116 117 ('a = "#string"', False),
117 118 ('a = "#string" # comment', True),
118 119 ('a #comment not "string"', True),
119 120 ]
120 121 tt.check_pairs(isp.has_comment, tests)
121 122
122 123
123 124 def test_get_input_encoding():
124 125 encoding = isp.get_input_encoding()
125 126 nt.assert_true(isinstance(encoding, basestring))
126 127 # simple-minded check that at least encoding a simple string works with the
127 128 # encoding we got.
128 129 nt.assert_equal(u'test'.encode(encoding), b'test')
129 130
130 131
131 132 class NoInputEncodingTestCase(unittest.TestCase):
132 133 def setUp(self):
133 134 self.old_stdin = sys.stdin
134 135 class X: pass
135 136 fake_stdin = X()
136 137 sys.stdin = fake_stdin
137 138
138 139 def test(self):
139 140 # Verify that if sys.stdin has no 'encoding' attribute we do the right
140 141 # thing
141 142 enc = isp.get_input_encoding()
142 143 self.assertEqual(enc, 'ascii')
143 144
144 145 def tearDown(self):
145 146 sys.stdin = self.old_stdin
146 147
147 148
148 149 class InputSplitterTestCase(unittest.TestCase):
149 150 def setUp(self):
150 151 self.isp = isp.InputSplitter()
151 152
152 153 def test_reset(self):
153 154 isp = self.isp
154 155 isp.push('x=1')
155 156 isp.reset()
156 157 self.assertEqual(isp._buffer, [])
157 158 self.assertEqual(isp.indent_spaces, 0)
158 159 self.assertEqual(isp.source, '')
159 160 self.assertEqual(isp.code, None)
160 161 self.assertEqual(isp._is_complete, False)
161 162
162 163 def test_source(self):
163 164 self.isp._store('1')
164 165 self.isp._store('2')
165 166 self.assertEqual(self.isp.source, '1\n2\n')
166 167 self.assertTrue(len(self.isp._buffer)>0)
167 168 self.assertEqual(self.isp.source_reset(), '1\n2\n')
168 169 self.assertEqual(self.isp._buffer, [])
169 170 self.assertEqual(self.isp.source, '')
170 171
171 172 def test_indent(self):
172 173 isp = self.isp # shorthand
173 174 isp.push('x=1')
174 175 self.assertEqual(isp.indent_spaces, 0)
175 176 isp.push('if 1:\n x=1')
176 177 self.assertEqual(isp.indent_spaces, 4)
177 178 isp.push('y=2\n')
178 179 self.assertEqual(isp.indent_spaces, 0)
179 180
180 181 def test_indent2(self):
181 182 # In cell mode, inputs must be fed in whole blocks, so skip this test
182 183 if self.isp.input_mode == 'cell': return
183 184
184 185 isp = self.isp
185 186 isp.push('if 1:')
186 187 self.assertEqual(isp.indent_spaces, 4)
187 188 isp.push(' x=1')
188 189 self.assertEqual(isp.indent_spaces, 4)
189 190 # Blank lines shouldn't change the indent level
190 191 isp.push(' '*2)
191 192 self.assertEqual(isp.indent_spaces, 4)
192 193
193 194 def test_indent3(self):
194 195 # In cell mode, inputs must be fed in whole blocks, so skip this test
195 196 if self.isp.input_mode == 'cell': return
196 197
197 198 isp = self.isp
198 199 # When a multiline statement contains parens or multiline strings, we
199 200 # shouldn't get confused.
200 201 isp.push("if 1:")
201 202 isp.push(" x = (1+\n 2)")
202 203 self.assertEqual(isp.indent_spaces, 4)
203 204
204 205 def test_indent4(self):
205 206 # In cell mode, inputs must be fed in whole blocks, so skip this test
206 207 if self.isp.input_mode == 'cell': return
207 208
208 209 isp = self.isp
209 210 # whitespace after ':' should not screw up indent level
210 211 isp.push('if 1: \n x=1')
211 212 self.assertEqual(isp.indent_spaces, 4)
212 213 isp.push('y=2\n')
213 214 self.assertEqual(isp.indent_spaces, 0)
214 215 isp.push('if 1:\t\n x=1')
215 216 self.assertEqual(isp.indent_spaces, 4)
216 217 isp.push('y=2\n')
217 218 self.assertEqual(isp.indent_spaces, 0)
218 219
219 220 def test_dedent_pass(self):
220 221 isp = self.isp # shorthand
221 222 # should NOT cause dedent
222 223 isp.push('if 1:\n passes = 5')
223 224 self.assertEqual(isp.indent_spaces, 4)
224 225 isp.push('if 1:\n pass')
225 226 self.assertEqual(isp.indent_spaces, 0)
226 227 isp.push('if 1:\n pass ')
227 228 self.assertEqual(isp.indent_spaces, 0)
228 229
229 230 def test_dedent_raise(self):
230 231 isp = self.isp # shorthand
231 232 # should NOT cause dedent
232 233 isp.push('if 1:\n raised = 4')
233 234 self.assertEqual(isp.indent_spaces, 4)
234 235 isp.push('if 1:\n raise TypeError()')
235 236 self.assertEqual(isp.indent_spaces, 0)
236 237 isp.push('if 1:\n raise')
237 238 self.assertEqual(isp.indent_spaces, 0)
238 239 isp.push('if 1:\n raise ')
239 240 self.assertEqual(isp.indent_spaces, 0)
240 241
241 242 def test_dedent_return(self):
242 243 isp = self.isp # shorthand
243 244 # should NOT cause dedent
244 245 isp.push('if 1:\n returning = 4')
245 246 self.assertEqual(isp.indent_spaces, 4)
246 247 isp.push('if 1:\n return 5 + 493')
247 248 self.assertEqual(isp.indent_spaces, 0)
248 249 isp.push('if 1:\n return')
249 250 self.assertEqual(isp.indent_spaces, 0)
250 251 isp.push('if 1:\n return ')
251 252 self.assertEqual(isp.indent_spaces, 0)
252 253 isp.push('if 1:\n return(0)')
253 254 self.assertEqual(isp.indent_spaces, 0)
254 255
255 256 def test_push(self):
256 257 isp = self.isp
257 258 self.assertTrue(isp.push('x=1'))
258 259
259 260 def test_push2(self):
260 261 isp = self.isp
261 262 self.assertFalse(isp.push('if 1:'))
262 263 for line in [' x=1', '# a comment', ' y=2']:
263 264 self.assertTrue(isp.push(line))
264 265
265 266 def test_push3(self):
266 267 isp = self.isp
267 268 isp.push('if True:')
268 269 isp.push(' a = 1')
269 270 self.assertFalse(isp.push('b = [1,'))
270 271
271 272 def test_replace_mode(self):
272 273 isp = self.isp
273 274 isp.input_mode = 'cell'
274 275 isp.push('x=1')
275 276 self.assertEqual(isp.source, 'x=1\n')
276 277 isp.push('x=2')
277 278 self.assertEqual(isp.source, 'x=2\n')
278 279
279 280 def test_push_accepts_more(self):
280 281 isp = self.isp
281 282 isp.push('x=1')
282 283 self.assertFalse(isp.push_accepts_more())
283 284
284 285 def test_push_accepts_more2(self):
285 286 # In cell mode, inputs must be fed in whole blocks, so skip this test
286 287 if self.isp.input_mode == 'cell': return
287 288
288 289 isp = self.isp
289 290 isp.push('if 1:')
290 291 self.assertTrue(isp.push_accepts_more())
291 292 isp.push(' x=1')
292 293 self.assertTrue(isp.push_accepts_more())
293 294 isp.push('')
294 295 self.assertFalse(isp.push_accepts_more())
295 296
296 297 def test_push_accepts_more3(self):
297 298 isp = self.isp
298 299 isp.push("x = (2+\n3)")
299 300 self.assertFalse(isp.push_accepts_more())
300 301
301 302 def test_push_accepts_more4(self):
302 303 # In cell mode, inputs must be fed in whole blocks, so skip this test
303 304 if self.isp.input_mode == 'cell': return
304 305
305 306 isp = self.isp
306 307 # When a multiline statement contains parens or multiline strings, we
307 308 # shouldn't get confused.
308 309 # FIXME: we should be able to better handle de-dents in statements like
309 310 # multiline strings and multiline expressions (continued with \ or
310 311 # parens). Right now we aren't handling the indentation tracking quite
311 312 # correctly with this, though in practice it may not be too much of a
312 313 # problem. We'll need to see.
313 314 isp.push("if 1:")
314 315 isp.push(" x = (2+")
315 316 isp.push(" 3)")
316 317 self.assertTrue(isp.push_accepts_more())
317 318 isp.push(" y = 3")
318 319 self.assertTrue(isp.push_accepts_more())
319 320 isp.push('')
320 321 self.assertFalse(isp.push_accepts_more())
321 322
322 323 def test_push_accepts_more5(self):
323 324 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 325 if self.isp.input_mode == 'cell': return
325 326
326 327 isp = self.isp
327 328 isp.push('try:')
328 329 isp.push(' a = 5')
329 330 isp.push('except:')
330 331 isp.push(' raise')
331 332 self.assertTrue(isp.push_accepts_more())
332 333
333 334 def test_continuation(self):
334 335 isp = self.isp
335 336 isp.push("import os, \\")
336 337 self.assertTrue(isp.push_accepts_more())
337 338 isp.push("sys")
338 339 self.assertFalse(isp.push_accepts_more())
339 340
340 341 def test_syntax_error(self):
341 342 isp = self.isp
342 343 # Syntax errors immediately produce a 'ready' block, so the invalid
343 344 # Python can be sent to the kernel for evaluation with possible ipython
344 345 # special-syntax conversion.
345 346 isp.push('run foo')
346 347 self.assertFalse(isp.push_accepts_more())
347 348
348 349 def test_unicode(self):
349 350 self.isp.push(u"PΓ©rez")
350 351 self.isp.push(u'\xc3\xa9')
351 352 self.isp.push(u"u'\xc3\xa9'")
352 353
353 354 class InteractiveLoopTestCase(unittest.TestCase):
354 355 """Tests for an interactive loop like a python shell.
355 356 """
356 357 def check_ns(self, lines, ns):
357 358 """Validate that the given input lines produce the resulting namespace.
358 359
359 360 Note: the input lines are given exactly as they would be typed in an
360 361 auto-indenting environment, as mini_interactive_loop above already does
361 362 auto-indenting and prepends spaces to the input.
362 363 """
363 364 src = mini_interactive_loop(pseudo_input(lines))
364 365 test_ns = {}
365 366 exec src in test_ns
366 367 # We can't check that the provided ns is identical to the test_ns,
367 368 # because Python fills test_ns with extra keys (copyright, etc). But
368 369 # we can check that the given dict is *contained* in test_ns
369 370 for k,v in ns.iteritems():
370 371 self.assertEqual(test_ns[k], v)
371 372
372 373 def test_simple(self):
373 374 self.check_ns(['x=1'], dict(x=1))
374 375
375 376 def test_simple2(self):
376 377 self.check_ns(['if 1:', 'x=2'], dict(x=2))
377 378
378 379 def test_xy(self):
379 380 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
380 381
381 382 def test_abc(self):
382 383 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
383 384
384 385 def test_multi(self):
385 386 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
386 387
387 388
388 389 def test_LineInfo():
389 390 """Simple test for LineInfo construction and str()"""
390 391 linfo = isp.LineInfo(' %cd /home')
391 392 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
392 393
393 394 # Transformer tests
394 395 def transform_checker(tests, func):
395 396 """Utility to loop over test inputs"""
396 397 for inp, tr in tests:
397 398 nt.assert_equals(func(inp), tr)
398 399
399 400 # Data for all the syntax tests in the form of lists of pairs of
400 401 # raw/transformed input. We store it here as a global dict so that we can use
401 402 # it both within single-function tests and also to validate the behavior of the
402 403 # larger objects
403 404
404 405 syntax = \
405 406 dict(assign_system =
406 [('a =! ls', 'a = get_ipython().getoutput(u"ls")'),
407 ('b = !ls', 'b = get_ipython().getoutput(u"ls")'),
407 [(i,py3compat.u_format(o)) for i,o in \
408 [('a =! ls', 'a = get_ipython().getoutput({u}"ls")'),
409 ('b = !ls', 'b = get_ipython().getoutput({u}"ls")'),
408 410 ('x=1', 'x=1'), # normal input is unmodified
409 411 (' ',' '), # blank lines are kept intact
410 ],
412 ]],
411 413
412 414 assign_magic =
413 [('a =% who', 'a = get_ipython().magic(u"who")'),
414 ('b = %who', 'b = get_ipython().magic(u"who")'),
415 [(i,py3compat.u_format(o)) for i,o in \
416 [('a =% who', 'a = get_ipython().magic({u}"who")'),
417 ('b = %who', 'b = get_ipython().magic({u}"who")'),
415 418 ('x=1', 'x=1'), # normal input is unmodified
416 419 (' ',' '), # blank lines are kept intact
417 ],
420 ]],
418 421
419 422 classic_prompt =
420 423 [('>>> x=1', 'x=1'),
421 424 ('x=1', 'x=1'), # normal input is unmodified
422 425 (' ', ' '), # blank lines are kept intact
423 426 ('... ', ''), # continuation prompts
424 427 ],
425 428
426 429 ipy_prompt =
427 430 [('In [1]: x=1', 'x=1'),
428 431 ('x=1', 'x=1'), # normal input is unmodified
429 432 (' ',' '), # blank lines are kept intact
430 433 (' ....: ', ''), # continuation prompts
431 434 ],
432 435
433 436 # Tests for the escape transformer to leave normal code alone
434 437 escaped_noesc =
435 438 [ (' ', ' '),
436 439 ('x=1', 'x=1'),
437 440 ],
438 441
439 442 # System calls
440 443 escaped_shell =
441 [ ('!ls', 'get_ipython().system(u"ls")'),
444 [(i,py3compat.u_format(o)) for i,o in \
445 [ ('!ls', 'get_ipython().system({u}"ls")'),
442 446 # Double-escape shell, this means to capture the output of the
443 447 # subprocess and return it
444 ('!!ls', 'get_ipython().getoutput(u"ls")'),
445 ],
448 ('!!ls', 'get_ipython().getoutput({u}"ls")'),
449 ]],
446 450
447 451 # Help/object info
448 452 escaped_help =
453 [(i,py3compat.u_format(o)) for i,o in \
449 454 [ ('?', 'get_ipython().show_usage()'),
450 ('?x1', 'get_ipython().magic(u"pinfo x1")'),
451 ('??x2', 'get_ipython().magic(u"pinfo2 x2")'),
452 ('?a.*s', 'get_ipython().magic(u"psearch a.*s")'),
453 ('?%hist', 'get_ipython().magic(u"pinfo %hist")'),
454 ('?abc = qwe', 'get_ipython().magic(u"pinfo abc")'),
455 ],
455 ('?x1', 'get_ipython().magic({u}"pinfo x1")'),
456 ('??x2', 'get_ipython().magic({u}"pinfo2 x2")'),
457 ('?a.*s', 'get_ipython().magic({u}"psearch a.*s")'),
458 ('?%hist', 'get_ipython().magic({u}"pinfo %hist")'),
459 ('?abc = qwe', 'get_ipython().magic({u}"pinfo abc")'),
460 ]],
456 461
457 462 end_help =
458 [ ('x3?', 'get_ipython().magic(u"pinfo x3")'),
459 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
460 ('%hist?', 'get_ipython().magic(u"pinfo %hist")'),
461 ('f*?', 'get_ipython().magic(u"psearch f*")'),
462 ('ax.*aspe*?', 'get_ipython().magic(u"psearch ax.*aspe*")'),
463 ('a = abc?', 'get_ipython().magic(u"pinfo abc", next_input=u"a = abc")'),
464 ('a = abc.qe??', 'get_ipython().magic(u"pinfo2 abc.qe", next_input=u"a = abc.qe")'),
465 ('a = *.items?', 'get_ipython().magic(u"psearch *.items", next_input=u"a = *.items")'),
466 ('plot(a?', 'get_ipython().magic(u"pinfo a", next_input=u"plot(a")'),
463 [(i,py3compat.u_format(o)) for i,o in \
464 [ ('x3?', 'get_ipython().magic({u}"pinfo x3")'),
465 ('x4??', 'get_ipython().magic({u}"pinfo2 x4")'),
466 ('%hist?', 'get_ipython().magic({u}"pinfo %hist")'),
467 ('f*?', 'get_ipython().magic({u}"psearch f*")'),
468 ('ax.*aspe*?', 'get_ipython().magic({u}"psearch ax.*aspe*")'),
469 ('a = abc?', 'get_ipython().magic({u}"pinfo abc", next_input={u}"a = abc")'),
470 ('a = abc.qe??', 'get_ipython().magic({u}"pinfo2 abc.qe", next_input={u}"a = abc.qe")'),
471 ('a = *.items?', 'get_ipython().magic({u}"psearch *.items", next_input={u}"a = *.items")'),
472 ('plot(a?', 'get_ipython().magic({u}"pinfo a", next_input={u}"plot(a")'),
467 473 ('a*2 #comment?', 'a*2 #comment?'),
468 ],
474 ]],
469 475
470 476 # Explicit magic calls
471 477 escaped_magic =
472 [ ('%cd', 'get_ipython().magic(u"cd")'),
473 ('%cd /home', 'get_ipython().magic(u"cd /home")'),
474 (' %magic', ' get_ipython().magic(u"magic")'),
475 ],
478 [(i,py3compat.u_format(o)) for i,o in \
479 [ ('%cd', 'get_ipython().magic({u}"cd")'),
480 ('%cd /home', 'get_ipython().magic({u}"cd /home")'),
481 (' %magic', ' get_ipython().magic({u}"magic")'),
482 ]],
476 483
477 484 # Quoting with separate arguments
478 485 escaped_quote =
479 486 [ (',f', 'f("")'),
480 487 (',f x', 'f("x")'),
481 488 (' ,f y', ' f("y")'),
482 489 (',f a b', 'f("a", "b")'),
483 490 ],
484 491
485 492 # Quoting with single argument
486 493 escaped_quote2 =
487 494 [ (';f', 'f("")'),
488 495 (';f x', 'f("x")'),
489 496 (' ;f y', ' f("y")'),
490 497 (';f a b', 'f("a b")'),
491 498 ],
492 499
493 500 # Simply apply parens
494 501 escaped_paren =
495 502 [ ('/f', 'f()'),
496 503 ('/f x', 'f(x)'),
497 504 (' /f y', ' f(y)'),
498 505 ('/f a b', 'f(a, b)'),
499 506 ],
500 507
501 508 # Check that we transform prompts before other transforms
502 509 mixed =
503 [ ('In [1]: %lsmagic', 'get_ipython().magic(u"lsmagic")'),
504 ('>>> %lsmagic', 'get_ipython().magic(u"lsmagic")'),
505 ('In [2]: !ls', 'get_ipython().system(u"ls")'),
506 ('In [3]: abs?', 'get_ipython().magic(u"pinfo abs")'),
507 ('In [4]: b = %who', 'b = get_ipython().magic(u"who")'),
508 ],
510 [(i,py3compat.u_format(o)) for i,o in \
511 [ ('In [1]: %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
512 ('>>> %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
513 ('In [2]: !ls', 'get_ipython().system({u}"ls")'),
514 ('In [3]: abs?', 'get_ipython().magic({u}"pinfo abs")'),
515 ('In [4]: b = %who', 'b = get_ipython().magic({u}"who")'),
516 ]],
509 517 )
510 518
511 519 # multiline syntax examples. Each of these should be a list of lists, with
512 520 # each entry itself having pairs of raw/transformed input. The union (with
513 521 # '\n'.join() of the transformed inputs is what the splitter should produce
514 522 # when fed the raw lines one at a time via push.
515 523 syntax_ml = \
516 524 dict(classic_prompt =
517 525 [ [('>>> for i in range(10):','for i in range(10):'),
518 526 ('... print i',' print i'),
519 527 ('... ', ''),
520 528 ],
521 529 ],
522 530
523 531 ipy_prompt =
524 532 [ [('In [24]: for i in range(10):','for i in range(10):'),
525 533 (' ....: print i',' print i'),
526 534 (' ....: ', ''),
527 535 ],
528 536 ],
529 537 )
530 538
531 539
532 540 def test_assign_system():
533 541 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
534 542
535 543
536 544 def test_assign_magic():
537 545 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
538 546
539 547
540 548 def test_classic_prompt():
541 549 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
542 550 for example in syntax_ml['classic_prompt']:
543 551 transform_checker(example, isp.transform_classic_prompt)
544 552
545 553
546 554 def test_ipy_prompt():
547 555 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
548 556 for example in syntax_ml['ipy_prompt']:
549 557 transform_checker(example, isp.transform_ipy_prompt)
550 558
551 559 def test_end_help():
552 560 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
553 561
554 562 def test_escaped_noesc():
555 563 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
556 564
557 565
558 566 def test_escaped_shell():
559 567 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
560 568
561 569
562 570 def test_escaped_help():
563 571 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
564 572
565 573
566 574 def test_escaped_magic():
567 575 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
568 576
569 577
570 578 def test_escaped_quote():
571 579 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
572 580
573 581
574 582 def test_escaped_quote2():
575 583 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
576 584
577 585
578 586 def test_escaped_paren():
579 587 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
580 588
581 589
582 590 class IPythonInputTestCase(InputSplitterTestCase):
583 591 """By just creating a new class whose .isp is a different instance, we
584 592 re-run the same test battery on the new input splitter.
585 593
586 594 In addition, this runs the tests over the syntax and syntax_ml dicts that
587 595 were tested by individual functions, as part of the OO interface.
588 596
589 597 It also makes some checks on the raw buffer storage.
590 598 """
591 599
592 600 def setUp(self):
593 601 self.isp = isp.IPythonInputSplitter(input_mode='line')
594 602
595 603 def test_syntax(self):
596 604 """Call all single-line syntax tests from the main object"""
597 605 isp = self.isp
598 606 for example in syntax.itervalues():
599 607 for raw, out_t in example:
600 608 if raw.startswith(' '):
601 609 continue
602 610
603 611 isp.push(raw)
604 612 out, out_raw = isp.source_raw_reset()
605 613 self.assertEqual(out.rstrip(), out_t,
606 614 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
607 615 self.assertEqual(out_raw.rstrip(), raw.rstrip())
608 616
609 617 def test_syntax_multiline(self):
610 618 isp = self.isp
611 619 for example in syntax_ml.itervalues():
612 620 out_t_parts = []
613 621 raw_parts = []
614 622 for line_pairs in example:
615 623 for lraw, out_t_part in line_pairs:
616 624 isp.push(lraw)
617 625 out_t_parts.append(out_t_part)
618 626 raw_parts.append(lraw)
619 627
620 628 out, out_raw = isp.source_raw_reset()
621 629 out_t = '\n'.join(out_t_parts).rstrip()
622 630 raw = '\n'.join(raw_parts).rstrip()
623 631 self.assertEqual(out.rstrip(), out_t)
624 632 self.assertEqual(out_raw.rstrip(), raw)
625 633
626 634
627 635 class BlockIPythonInputTestCase(IPythonInputTestCase):
628 636
629 637 # Deactivate tests that don't make sense for the block mode
630 638 test_push3 = test_split = lambda s: None
631 639
632 640 def setUp(self):
633 641 self.isp = isp.IPythonInputSplitter(input_mode='cell')
634 642
635 643 def test_syntax_multiline(self):
636 644 isp = self.isp
637 645 for example in syntax_ml.itervalues():
638 646 raw_parts = []
639 647 out_t_parts = []
640 648 for line_pairs in example:
641 649 for raw, out_t_part in line_pairs:
642 650 raw_parts.append(raw)
643 651 out_t_parts.append(out_t_part)
644 652
645 653 raw = '\n'.join(raw_parts)
646 654 out_t = '\n'.join(out_t_parts)
647 655
648 656 isp.push(raw)
649 657 out, out_raw = isp.source_raw_reset()
650 658 # Match ignoring trailing whitespace
651 659 self.assertEqual(out.rstrip(), out_t.rstrip())
652 660 self.assertEqual(out_raw.rstrip(), raw.rstrip())
653 661
654 662
655 663 #-----------------------------------------------------------------------------
656 664 # Main - use as a script, mostly for developer experiments
657 665 #-----------------------------------------------------------------------------
658 666
659 667 if __name__ == '__main__':
660 668 # A simple demo for interactive experimentation. This code will not get
661 669 # picked up by any test suite.
662 670 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
663 671
664 672 # configure here the syntax to use, prompt and whether to autoindent
665 673 #isp, start_prompt = InputSplitter(), '>>> '
666 674 isp, start_prompt = IPythonInputSplitter(), 'In> '
667 675
668 676 autoindent = True
669 677 #autoindent = False
670 678
671 679 try:
672 680 while True:
673 681 prompt = start_prompt
674 682 while isp.push_accepts_more():
675 683 indent = ' '*isp.indent_spaces
676 684 if autoindent:
677 685 line = indent + raw_input(prompt+indent)
678 686 else:
679 687 line = raw_input(prompt)
680 688 isp.push(line)
681 689 prompt = '... '
682 690
683 691 # Here we just return input so we can use it in a test suite, but a
684 692 # real interpreter would instead send it for execution somewhere.
685 693 #src = isp.source; raise EOFError # dbg
686 694 src, raw = isp.source_raw_reset()
687 695 print 'Input source was:\n', src
688 696 print 'Raw source was:\n', raw
689 697 except EOFError:
690 698 print 'Bye'
@@ -1,271 +1,271 b''
1 1 """Tests for the key interactiveshell module, where the main ipython class is defined.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # stdlib
8 8 import os
9 9 import shutil
10 10 import tempfile
11 11
12 12 # third party
13 13 import nose.tools as nt
14 14
15 15 # our own packages
16 16 from IPython.testing import decorators as dec
17 17 from IPython.testing.globalipapp import get_ipython
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Globals
21 21 #-----------------------------------------------------------------------------
22 22
23 23 # Get the public instance of IPython
24 24 ip = get_ipython()
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Test functions
28 28 #-----------------------------------------------------------------------------
29 29
30 30 @dec.parametric
31 31 def test_reset():
32 32 """reset must clear most namespaces."""
33 33 # The number of variables in the private user_ns_hidden is not zero, but it
34 34 # should be constant regardless of what we do
35 35 nvars_config_ns = len(ip.user_ns_hidden)
36 36
37 37 # Check that reset runs without error
38 38 ip.reset()
39 39
40 40 # Once we've reset it (to clear of any junk that might have been there from
41 41 # other tests, we can count how many variables are in the user's namespace
42 42 nvars_user_ns = len(ip.user_ns)
43 43
44 44 # Now add a few variables to user_ns, and check that reset clears them
45 45 ip.user_ns['x'] = 1
46 46 ip.user_ns['y'] = 1
47 47 ip.reset()
48 48
49 49 # Finally, check that all namespaces have only as many variables as we
50 50 # expect to find in them:
51 51 for ns in ip.ns_refs_table:
52 52 if ns is ip.user_ns:
53 53 nvars_expected = nvars_user_ns
54 54 elif ns is ip.user_ns_hidden:
55 55 nvars_expected = nvars_config_ns
56 56 else:
57 57 nvars_expected = 0
58 58
59 59 yield nt.assert_equals(len(ns), nvars_expected)
60 60
61 61
62 62 # Tests for reporting of exceptions in various modes, handling of SystemExit,
63 63 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
64 64
65 65 def doctest_tb_plain():
66 66 """
67 67 In [18]: xmode plain
68 68 Exception reporting mode: Plain
69 69
70 70 In [19]: run simpleerr.py
71 71 Traceback (most recent call last):
72 72 ...line 32, in <module>
73 73 bar(mode)
74 74 ...line 16, in bar
75 75 div0()
76 76 ...line 8, in div0
77 77 x/y
78 78 ZeroDivisionError: ...
79 79 """
80 80
81 81
82 82 def doctest_tb_context():
83 83 """
84 84 In [3]: xmode context
85 85 Exception reporting mode: Context
86 86
87 87 In [4]: run simpleerr.py
88 88 ---------------------------------------------------------------------------
89 89 ZeroDivisionError Traceback (most recent call last)
90 90 <BLANKLINE>
91 91 ... in <module>()
92 92 30 mode = 'div'
93 93 31
94 94 ---> 32 bar(mode)
95 95 <BLANKLINE>
96 96 ... in bar(mode)
97 97 14 "bar"
98 98 15 if mode=='div':
99 99 ---> 16 div0()
100 100 17 elif mode=='exit':
101 101 18 try:
102 102 <BLANKLINE>
103 103 ... in div0()
104 104 6 x = 1
105 105 7 y = 0
106 106 ----> 8 x/y
107 107 9
108 108 10 def sysexit(stat, mode):
109 109 <BLANKLINE>
110 110 ZeroDivisionError: ...
111 111 """
112 112
113 113
114 114 def doctest_tb_verbose():
115 115 """
116 116 In [5]: xmode verbose
117 117 Exception reporting mode: Verbose
118 118
119 119 In [6]: run simpleerr.py
120 120 ---------------------------------------------------------------------------
121 121 ZeroDivisionError Traceback (most recent call last)
122 122 <BLANKLINE>
123 123 ... in <module>()
124 124 30 mode = 'div'
125 125 31
126 126 ---> 32 bar(mode)
127 127 global bar = <function bar at ...>
128 128 global mode = 'div'
129 129 <BLANKLINE>
130 130 ... in bar(mode='div')
131 131 14 "bar"
132 132 15 if mode=='div':
133 133 ---> 16 div0()
134 134 global div0 = <function div0 at ...>
135 135 17 elif mode=='exit':
136 136 18 try:
137 137 <BLANKLINE>
138 138 ... in div0()
139 139 6 x = 1
140 140 7 y = 0
141 141 ----> 8 x/y
142 142 x = 1
143 143 y = 0
144 144 9
145 145 10 def sysexit(stat, mode):
146 146 <BLANKLINE>
147 147 ZeroDivisionError: ...
148 148 """
149 149
150
150 @py3compat.u_format
151 151 def doctest_tb_sysexit():
152 152 """
153 153 In [17]: %xmode plain
154 154 Exception reporting mode: Plain
155 155
156 156 In [18]: %run simpleerr.py exit
157 157 An exception has occurred, use %tb to see the full traceback.
158 SystemExit: (1, u'Mode = exit')
158 SystemExit: (1, {u}'Mode = exit')
159 159
160 160 In [19]: %run simpleerr.py exit 2
161 161 An exception has occurred, use %tb to see the full traceback.
162 SystemExit: (2, u'Mode = exit')
162 SystemExit: (2, {u}'Mode = exit')
163 163
164 164 In [20]: %tb
165 165 Traceback (most recent call last):
166 166 File ... in <module>
167 167 bar(mode)
168 168 File ... line 22, in bar
169 169 sysexit(stat, mode)
170 170 File ... line 11, in sysexit
171 171 raise SystemExit(stat, 'Mode = %s' % mode)
172 SystemExit: (2, u'Mode = exit')
172 SystemExit: (2, {u}'Mode = exit')
173 173
174 174 In [21]: %xmode context
175 175 Exception reporting mode: Context
176 176
177 177 In [22]: %tb
178 178 ---------------------------------------------------------------------------
179 179 SystemExit Traceback (most recent call last)
180 180 <BLANKLINE>
181 181 ...<module>()
182 182 30 mode = 'div'
183 183 31
184 184 ---> 32 bar(mode)
185 185 <BLANKLINE>
186 186 ...bar(mode)
187 187 20 except:
188 188 21 stat = 1
189 189 ---> 22 sysexit(stat, mode)
190 190 23 else:
191 191 24 raise ValueError('Unknown mode')
192 192 <BLANKLINE>
193 193 ...sysexit(stat, mode)
194 194 9
195 195 10 def sysexit(stat, mode):
196 196 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
197 197 12
198 198 13 def bar(mode):
199 199 <BLANKLINE>
200 SystemExit: (2, u'Mode = exit')
200 SystemExit: (2, {u}'Mode = exit')
201 201
202 202 In [23]: %xmode verbose
203 203 Exception reporting mode: Verbose
204 204
205 205 In [24]: %tb
206 206 ---------------------------------------------------------------------------
207 207 SystemExit Traceback (most recent call last)
208 208 <BLANKLINE>
209 209 ... in <module>()
210 210 30 mode = 'div'
211 211 31
212 212 ---> 32 bar(mode)
213 213 global bar = <function bar at ...>
214 global mode = u'exit'
214 global mode = {u}'exit'
215 215 <BLANKLINE>
216 ... in bar(mode=u'exit')
216 ... in bar(mode={u}'exit')
217 217 20 except:
218 218 21 stat = 1
219 219 ---> 22 sysexit(stat, mode)
220 220 global sysexit = <function sysexit at ...>
221 221 stat = 2
222 mode = u'exit'
222 mode = {u}'exit'
223 223 23 else:
224 224 24 raise ValueError('Unknown mode')
225 225 <BLANKLINE>
226 ... in sysexit(stat=2, mode=u'exit')
226 ... in sysexit(stat=2, mode={u}'exit')
227 227 9
228 228 10 def sysexit(stat, mode):
229 229 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
230 230 global SystemExit = undefined
231 231 stat = 2
232 mode = u'exit'
232 mode = {u}'exit'
233 233 12
234 234 13 def bar(mode):
235 235 <BLANKLINE>
236 SystemExit: (2, u'Mode = exit')
236 SystemExit: (2, {u}'Mode = exit')
237 237 """
238 238
239 239
240 240 def test_run_cell():
241 241 import textwrap
242 242 ip.run_cell('a = 10\na+=1')
243 243 ip.run_cell('assert a == 11\nassert 1')
244 244
245 245 nt.assert_equals(ip.user_ns['a'], 11)
246 246 complex = textwrap.dedent("""
247 247 if 1:
248 248 print "hello"
249 249 if 1:
250 250 print "world"
251 251
252 252 if 2:
253 253 print "foo"
254 254
255 255 if 3:
256 256 print "bar"
257 257
258 258 if 4:
259 259 print "bar"
260 260
261 261 """)
262 262 # Simply verifies that this kind of input is run
263 263 ip.run_cell(complex)
264 264
265 265
266 266 def test_db():
267 267 """Test the internal database used for variable persistence."""
268 268 ip.db['__unittest_'] = 12
269 269 nt.assert_equals(ip.db['__unittest_'], 12)
270 270 del ip.db['__unittest_']
271 271 assert '__unittest_' not in ip.db
@@ -1,462 +1,467 b''
1 1 """Tests for various magic functions.
2 2
3 3 Needs to be run by nose (to make ipython session available).
4 4 """
5 5 from __future__ import absolute_import
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Imports
9 9 #-----------------------------------------------------------------------------
10 10
11 11 import os
12 12 import sys
13 13 import tempfile
14 14 import types
15 15 from StringIO import StringIO
16 16
17 17 import nose.tools as nt
18 18
19 19 from IPython.utils.path import get_long_path_name
20 20 from IPython.testing import decorators as dec
21 21 from IPython.testing import tools as tt
22 from IPython.utils import py3compat
22 23
23 24 #-----------------------------------------------------------------------------
24 25 # Test functions begin
25 26 #-----------------------------------------------------------------------------
26 27 def test_rehashx():
27 28 # clear up everything
28 29 _ip = get_ipython()
29 30 _ip.alias_manager.alias_table.clear()
30 31 del _ip.db['syscmdlist']
31 32
32 33 _ip.magic('rehashx')
33 34 # Practically ALL ipython development systems will have more than 10 aliases
34 35
35 36 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
36 37 for key, val in _ip.alias_manager.alias_table.iteritems():
37 38 # we must strip dots from alias names
38 39 nt.assert_true('.' not in key)
39 40
40 41 # rehashx must fill up syscmdlist
41 42 scoms = _ip.db['syscmdlist']
42 43 yield (nt.assert_true, len(scoms) > 10)
43 44
44 45
45 46 def test_magic_parse_options():
46 47 """Test that we don't mangle paths when parsing magic options."""
47 48 ip = get_ipython()
48 49 path = 'c:\\x'
49 50 opts = ip.parse_options('-f %s' % path,'f:')[0]
50 51 # argv splitting is os-dependent
51 52 if os.name == 'posix':
52 53 expected = 'c:x'
53 54 else:
54 55 expected = path
55 56 nt.assert_equals(opts['f'], expected)
56 57
57 58
58 59 def doctest_hist_f():
59 60 """Test %hist -f with temporary filename.
60 61
61 62 In [9]: import tempfile
62 63
63 64 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
64 65
65 66 In [11]: %hist -nl -f $tfile 3
66 67
67 68 In [13]: import os; os.unlink(tfile)
68 69 """
69 70
70 71
71 72 def doctest_hist_r():
72 73 """Test %hist -r
73 74
74 75 XXX - This test is not recording the output correctly. For some reason, in
75 76 testing mode the raw history isn't getting populated. No idea why.
76 77 Disabling the output checking for now, though at least we do run it.
77 78
78 79 In [1]: 'hist' in _ip.lsmagic()
79 80 Out[1]: True
80 81
81 82 In [2]: x=1
82 83
83 84 In [3]: %hist -rl 2
84 85 x=1 # random
85 86 %hist -r 2
86 87 """
87 88
88 89 def doctest_hist_op():
89 90 """Test %hist -op
90 91
91 In [1]: class b:
92 ...: pass
92 In [1]: class b(float):
93 ...: pass
93 94 ...:
94 95
95 In [2]: class s(b):
96 ...: def __str__(self):
97 ...: return 's'
96 In [2]: class s(object):
97 ...: def __str__(self):
98 ...: return 's'
98 99 ...:
99 100
100 101 In [3]:
101 102
102 103 In [4]: class r(b):
103 ...: def __repr__(self):
104 ...: return 'r'
104 ...: def __repr__(self):
105 ...: return 'r'
105 106 ...:
106 107
107 108 In [5]: class sr(s,r): pass
108 109 ...:
109 110
110 111 In [6]:
111 112
112 113 In [7]: bb=b()
113 114
114 115 In [8]: ss=s()
115 116
116 117 In [9]: rr=r()
117 118
118 119 In [10]: ssrr=sr()
119 120
120 In [11]: bb
121 Out[11]: <...b instance at ...>
121 In [11]: 4.5
122 Out[11]: 4.5
122 123
123 In [12]: ss
124 Out[12]: <...s instance at ...>
124 In [12]: str(ss)
125 Out[12]: 's'
125 126
126 127 In [13]:
127 128
128 129 In [14]: %hist -op
129 130 >>> class b:
130 131 ... pass
131 132 ...
132 133 >>> class s(b):
133 134 ... def __str__(self):
134 135 ... return 's'
135 136 ...
136 137 >>>
137 138 >>> class r(b):
138 139 ... def __repr__(self):
139 140 ... return 'r'
140 141 ...
141 142 >>> class sr(s,r): pass
142 143 >>>
143 144 >>> bb=b()
144 145 >>> ss=s()
145 146 >>> rr=r()
146 147 >>> ssrr=sr()
147 >>> bb
148 <...b instance at ...>
149 >>> ss
150 <...s instance at ...>
148 >>> 4.5
149 4.5
150 >>> str(ss)
151 's'
151 152 >>>
152 153 """
153 154
154 155 def test_macro():
155 156 ip = get_ipython()
156 157 ip.history_manager.reset() # Clear any existing history.
157 158 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
158 159 for i, cmd in enumerate(cmds, start=1):
159 160 ip.history_manager.store_inputs(i, cmd)
160 161 ip.magic("macro test 1-3")
161 162 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
162 163
163 164 # List macros.
164 165 assert "test" in ip.magic("macro")
165 166
166 167 def test_macro_run():
167 168 """Test that we can run a multi-line macro successfully."""
168 169 ip = get_ipython()
169 170 ip.history_manager.reset()
170 cmds = ["a=10", "a+=1", "print a", "%macro test 2-3"]
171 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
172 "%macro test 2-3"]
171 173 for cmd in cmds:
172 174 ip.run_cell(cmd)
173 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint a\n")
175 nt.assert_equal(ip.user_ns["test"].value,
176 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
174 177 original_stdout = sys.stdout
175 178 new_stdout = StringIO()
176 179 sys.stdout = new_stdout
177 180 try:
178 181 ip.run_cell("test")
179 182 nt.assert_true("12" in new_stdout.getvalue())
180 183 ip.run_cell("test")
181 184 nt.assert_true("13" in new_stdout.getvalue())
182 185 finally:
183 186 sys.stdout = original_stdout
184 187 new_stdout.close()
185 188
186 189
187 190 # XXX failing for now, until we get clearcmd out of quarantine. But we should
188 191 # fix this and revert the skip to happen only if numpy is not around.
189 192 #@dec.skipif_not_numpy
190 193 @dec.skip_known_failure
191 194 def test_numpy_clear_array_undec():
192 195 from IPython.extensions import clearcmd
193 196
194 197 _ip.ex('import numpy as np')
195 198 _ip.ex('a = np.empty(2)')
196 199 yield (nt.assert_true, 'a' in _ip.user_ns)
197 200 _ip.magic('clear array')
198 201 yield (nt.assert_false, 'a' in _ip.user_ns)
199 202
200 203
201 204 # Multiple tests for clipboard pasting
202 205 @dec.parametric
203 206 def test_paste():
204 207 _ip = get_ipython()
205 208 def paste(txt, flags='-q'):
206 209 """Paste input text, by default in quiet mode"""
207 210 hooks.clipboard_get = lambda : txt
208 211 _ip.magic('paste '+flags)
209 212
210 213 # Inject fake clipboard hook but save original so we can restore it later
211 214 hooks = _ip.hooks
212 215 user_ns = _ip.user_ns
213 216 original_clip = hooks.clipboard_get
214 217
215 218 try:
216 219 # This try/except with an emtpy except clause is here only because
217 220 # try/yield/finally is invalid syntax in Python 2.4. This will be
218 221 # removed when we drop 2.4-compatibility, and the emtpy except below
219 222 # will be changed to a finally.
220 223
221 224 # Run tests with fake clipboard function
222 225 user_ns.pop('x', None)
223 226 paste('x=1')
224 227 yield nt.assert_equal(user_ns['x'], 1)
225 228
226 229 user_ns.pop('x', None)
227 230 paste('>>> x=2')
228 231 yield nt.assert_equal(user_ns['x'], 2)
229 232
230 233 paste("""
231 234 >>> x = [1,2,3]
232 235 >>> y = []
233 236 >>> for i in x:
234 237 ... y.append(i**2)
235 238 ...
236 239 """)
237 240 yield nt.assert_equal(user_ns['x'], [1,2,3])
238 241 yield nt.assert_equal(user_ns['y'], [1,4,9])
239 242
240 243 # Now, test that paste -r works
241 244 user_ns.pop('x', None)
242 245 yield nt.assert_false('x' in user_ns)
243 246 _ip.magic('paste -r')
244 247 yield nt.assert_equal(user_ns['x'], [1,2,3])
245 248
246 249 # Also test paste echoing, by temporarily faking the writer
247 250 w = StringIO()
248 251 writer = _ip.write
249 252 _ip.write = w.write
250 253 code = """
251 254 a = 100
252 255 b = 200"""
253 256 try:
254 257 paste(code,'')
255 258 out = w.getvalue()
256 259 finally:
257 260 _ip.write = writer
258 261 yield nt.assert_equal(user_ns['a'], 100)
259 262 yield nt.assert_equal(user_ns['b'], 200)
260 263 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
261 264
262 265 finally:
263 266 # This should be in a finally clause, instead of the bare except above.
264 267 # Restore original hook
265 268 hooks.clipboard_get = original_clip
266 269
267 270
268 271 def test_time():
269 272 _ip.magic('time None')
270 273
271 274
275 @py3compat.doctest_refactor_print
272 276 def doctest_time():
273 277 """
274 278 In [10]: %time None
275 279 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
276 280 Wall time: 0.00 s
277 281
278 282 In [11]: def f(kmjy):
279 283 ....: %time print 2*kmjy
280 284
281 285 In [12]: f(3)
282 286 6
283 287 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
284 288 Wall time: 0.00 s
285 289 """
286 290
287 291
288 292 def test_doctest_mode():
289 293 "Toggle doctest_mode twice, it should be a no-op and run without error"
290 294 _ip.magic('doctest_mode')
291 295 _ip.magic('doctest_mode')
292 296
293 297
294 298 def test_parse_options():
295 299 """Tests for basic options parsing in magics."""
296 300 # These are only the most minimal of tests, more should be added later. At
297 301 # the very least we check that basic text/unicode calls work OK.
298 302 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
299 303 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
300 304
301 305
302 306 def test_dirops():
303 307 """Test various directory handling operations."""
304 308 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
305 309 curpath = os.getcwdu
306 310 startdir = os.getcwdu()
307 311 ipdir = _ip.ipython_dir
308 312 try:
309 313 _ip.magic('cd "%s"' % ipdir)
310 314 nt.assert_equal(curpath(), ipdir)
311 315 _ip.magic('cd -')
312 316 nt.assert_equal(curpath(), startdir)
313 317 _ip.magic('pushd "%s"' % ipdir)
314 318 nt.assert_equal(curpath(), ipdir)
315 319 _ip.magic('popd')
316 320 nt.assert_equal(curpath(), startdir)
317 321 finally:
318 322 os.chdir(startdir)
319 323
320 324
321 325 def check_cpaste(code, should_fail=False):
322 326 """Execute code via 'cpaste' and ensure it was executed, unless
323 327 should_fail is set.
324 328 """
325 329 _ip.user_ns['code_ran'] = False
326 330
327 331 src = StringIO()
328 332 src.write('\n')
329 333 src.write(code)
330 334 src.write('\n--\n')
331 335 src.seek(0)
332 336
333 337 stdin_save = sys.stdin
334 338 sys.stdin = src
335 339
336 340 try:
337 341 _ip.magic('cpaste')
338 342 except:
339 343 if not should_fail:
340 344 raise AssertionError("Failure not expected : '%s'" %
341 345 code)
342 346 else:
343 347 assert _ip.user_ns['code_ran']
344 348 if should_fail:
345 349 raise AssertionError("Failure expected : '%s'" % code)
346 350 finally:
347 351 sys.stdin = stdin_save
348 352
349 353
350 354 def test_cpaste():
351 355 """Test cpaste magic"""
352 356
353 357 def run():
354 358 """Marker function: sets a flag when executed.
355 359 """
356 360 _ip.user_ns['code_ran'] = True
357 361 return 'run' # return string so '+ run()' doesn't result in success
358 362
359 363 tests = {'pass': ["> > > run()",
360 364 ">>> > run()",
361 365 "+++ run()",
362 366 "++ run()",
363 367 " >>> run()"],
364 368
365 369 'fail': ["+ + run()",
366 370 " ++ run()"]}
367 371
368 372 _ip.user_ns['run'] = run
369 373
370 374 for code in tests['pass']:
371 375 check_cpaste(code)
372 376
373 377 for code in tests['fail']:
374 378 check_cpaste(code, should_fail=True)
375 379
376 380 def test_xmode():
377 381 # Calling xmode three times should be a no-op
378 382 xmode = _ip.InteractiveTB.mode
379 383 for i in range(3):
380 384 _ip.magic("xmode")
381 385 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
382 386
383 387 def test_reset_hard():
384 388 monitor = []
385 389 class A(object):
386 390 def __del__(self):
387 391 monitor.append(1)
388 392 def __repr__(self):
389 393 return "<A instance>"
390 394
391 395 _ip.user_ns["a"] = A()
392 396 _ip.run_cell("a")
393 397
394 398 nt.assert_equal(monitor, [])
395 399 _ip.magic_reset("-f")
396 400 nt.assert_equal(monitor, [1])
397 401
398 402 class TestXdel(tt.TempFileMixin):
399 403 def test_xdel(self):
400 404 """Test that references from %run are cleared by xdel."""
401 405 src = ("class A(object):\n"
402 406 " monitor = []\n"
403 407 " def __del__(self):\n"
404 408 " self.monitor.append(1)\n"
405 409 "a = A()\n")
406 410 self.mktmp(src)
407 411 # %run creates some hidden references...
408 412 _ip.magic("run %s" % self.fname)
409 413 # ... as does the displayhook.
410 414 _ip.run_cell("a")
411 415
412 416 monitor = _ip.user_ns["A"].monitor
413 417 nt.assert_equal(monitor, [])
414 418
415 419 _ip.magic("xdel a")
416 420
417 421 # Check that a's __del__ method has been called.
418 422 nt.assert_equal(monitor, [1])
419 423
420 424 def doctest_who():
421 425 """doctest for %who
422 426
423 427 In [1]: %reset -f
424 428
425 429 In [2]: alpha = 123
426 430
427 431 In [3]: beta = 'beta'
428 432
429 433 In [4]: %who int
430 434 alpha
431 435
432 436 In [5]: %who str
433 437 beta
434 438
435 439 In [6]: %whos
436 440 Variable Type Data/Info
437 441 ----------------------------
438 442 alpha int 123
439 443 beta str beta
440 444
441 445 In [7]: %who_ls
442 446 Out[7]: ['alpha', 'beta']
443 447 """
444 448
449 @py3compat.u_format
445 450 def doctest_precision():
446 451 """doctest for %precision
447 452
448 453 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
449 454
450 455 In [2]: %precision 5
451 Out[2]: u'%.5f'
456 Out[2]: {u}'%.5f'
452 457
453 458 In [3]: f.float_format
454 Out[3]: u'%.5f'
459 Out[3]: {u}'%.5f'
455 460
456 461 In [4]: %precision %e
457 Out[4]: u'%e'
462 Out[4]: {u}'%e'
458 463
459 464 In [5]: f(3.1415927)
460 Out[5]: u'3.141593e+00'
465 Out[5]: {u}'3.141593e+00'
461 466 """
462 467
@@ -1,208 +1,210 b''
1 1 """Tests for code execution (%run and related), which is particularly tricky.
2 2
3 3 Because of how %run manages namespaces, and the fact that we are trying here to
4 4 verify subtle object deletion and reference counting issues, the %run tests
5 5 will be kept in this separate file. This makes it easier to aggregate in one
6 6 place the tricks needed to handle it; most other magics are much easier to test
7 7 and we do so in a common test_magic file.
8 8 """
9 9 from __future__ import absolute_import
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 import os
16 16 import sys
17 17 import tempfile
18 18
19 19 import nose.tools as nt
20 20 from nose import SkipTest
21 21
22 22 from IPython.testing import decorators as dec
23 23 from IPython.testing import tools as tt
24 from IPython.utils.py3compat import doctest_refactor_print
24 25
25 26 #-----------------------------------------------------------------------------
26 27 # Test functions begin
27 28 #-----------------------------------------------------------------------------
28 29
29 30 def doctest_refbug():
30 31 """Very nasty problem with references held by multiple runs of a script.
31 32 See: https://github.com/ipython/ipython/issues/141
32 33
33 34 In [1]: _ip.clear_main_mod_cache()
34 35 # random
35 36
36 37 In [2]: %run refbug
37 38
38 39 In [3]: call_f()
39 40 lowercased: hello
40 41
41 42 In [4]: %run refbug
42 43
43 44 In [5]: call_f()
44 45 lowercased: hello
45 46 lowercased: hello
46 47 """
47 48
48 49
49 50 def doctest_run_builtins():
50 51 r"""Check that %run doesn't damage __builtins__.
51 52
52 53 In [1]: import tempfile
53 54
54 55 In [2]: bid1 = id(__builtins__)
55 56
56 57 In [3]: fname = tempfile.mkstemp('.py')[1]
57 58
58 59 In [3]: f = open(fname,'w')
59 60
60 In [4]: f.write('pass\n')
61 In [4]: dummy= f.write('pass\n')
61 62
62 63 In [5]: f.flush()
63 64
64 65 In [6]: t1 = type(__builtins__)
65 66
66 67 In [7]: %run $fname
67 68
68 69 In [7]: f.close()
69 70
70 71 In [8]: bid2 = id(__builtins__)
71 72
72 73 In [9]: t2 = type(__builtins__)
73 74
74 75 In [10]: t1 == t2
75 76 Out[10]: True
76 77
77 78 In [10]: bid1 == bid2
78 79 Out[10]: True
79 80
80 81 In [12]: try:
81 82 ....: os.unlink(fname)
82 83 ....: except:
83 84 ....: pass
84 85 ....:
85 86 """
86 87
88 @doctest_refactor_print
87 89 def doctest_reset_del():
88 90 """Test that resetting doesn't cause errors in __del__ methods.
89 91
90 92 In [2]: class A(object):
91 93 ...: def __del__(self):
92 94 ...: print str("Hi")
93 95 ...:
94 96
95 97 In [3]: a = A()
96 98
97 99 In [4]: get_ipython().reset()
98 100 Hi
99 101
100 102 In [5]: 1+1
101 103 Out[5]: 2
102 104 """
103 105
104 106 # For some tests, it will be handy to organize them in a class with a common
105 107 # setup that makes a temp file
106 108
107 109 class TestMagicRunPass(tt.TempFileMixin):
108 110
109 111 def setup(self):
110 112 """Make a valid python temp file."""
111 113 self.mktmp('pass\n')
112 114
113 115 def run_tmpfile(self):
114 116 _ip = get_ipython()
115 117 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
116 118 # See below and ticket https://bugs.launchpad.net/bugs/366353
117 119 _ip.magic('run %s' % self.fname)
118 120
119 121 def test_builtins_id(self):
120 122 """Check that %run doesn't damage __builtins__ """
121 123 _ip = get_ipython()
122 124 # Test that the id of __builtins__ is not modified by %run
123 125 bid1 = id(_ip.user_ns['__builtins__'])
124 126 self.run_tmpfile()
125 127 bid2 = id(_ip.user_ns['__builtins__'])
126 128 tt.assert_equals(bid1, bid2)
127 129
128 130 def test_builtins_type(self):
129 131 """Check that the type of __builtins__ doesn't change with %run.
130 132
131 133 However, the above could pass if __builtins__ was already modified to
132 134 be a dict (it should be a module) by a previous use of %run. So we
133 135 also check explicitly that it really is a module:
134 136 """
135 137 _ip = get_ipython()
136 138 self.run_tmpfile()
137 139 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
138 140
139 141 def test_prompts(self):
140 142 """Test that prompts correctly generate after %run"""
141 143 self.run_tmpfile()
142 144 _ip = get_ipython()
143 145 p2 = str(_ip.displayhook.prompt2).strip()
144 146 nt.assert_equals(p2[:3], '...')
145 147
146 148
147 149 class TestMagicRunSimple(tt.TempFileMixin):
148 150
149 151 def test_simpledef(self):
150 152 """Test that simple class definitions work."""
151 153 src = ("class foo: pass\n"
152 154 "def f(): return foo()")
153 155 self.mktmp(src)
154 156 _ip.magic('run %s' % self.fname)
155 157 _ip.run_cell('t = isinstance(f(), foo)')
156 158 nt.assert_true(_ip.user_ns['t'])
157 159
158 160 def test_obj_del(self):
159 161 """Test that object's __del__ methods are called on exit."""
160 162 if sys.platform == 'win32':
161 163 try:
162 164 import win32api
163 165 except ImportError:
164 166 raise SkipTest("Test requires pywin32")
165 167 src = ("class A(object):\n"
166 168 " def __del__(self):\n"
167 169 " print 'object A deleted'\n"
168 170 "a = A()\n")
169 171 self.mktmp(src)
170 172 tt.ipexec_validate(self.fname, 'object A deleted')
171 173
172 174 @dec.skip_known_failure
173 175 def test_aggressive_namespace_cleanup(self):
174 176 """Test that namespace cleanup is not too aggressive GH-238
175 177
176 178 Returning from another run magic deletes the namespace"""
177 179 # see ticket https://github.com/ipython/ipython/issues/238
178 180 class secondtmp(tt.TempFileMixin): pass
179 181 empty = secondtmp()
180 182 empty.mktmp('')
181 183 src = ("ip = get_ipython()\n"
182 184 "for i in range(5):\n"
183 185 " try:\n"
184 186 " ip.magic('run %s')\n"
185 187 " except NameError, e:\n"
186 188 " print i;break\n" % empty.fname)
187 189 self.mktmp(src)
188 190 _ip.magic('run %s' % self.fname)
189 191 _ip.run_cell('ip == get_ipython()')
190 192 tt.assert_equals(_ip.user_ns['i'], 5)
191 193
192 194 @dec.skip_win32
193 195 def test_tclass(self):
194 196 mydir = os.path.dirname(__file__)
195 197 tc = os.path.join(mydir, 'tclass')
196 198 src = ("%%run '%s' C-first\n"
197 199 "%%run '%s' C-second\n"
198 200 "%%run '%s' C-third\n") % (tc, tc, tc)
199 201 self.mktmp(src, '.ipy')
200 202 out = """\
201 203 ARGV 1-: [u'C-first']
202 204 ARGV 1-: [u'C-second']
203 205 tclass.py: deleting object: C-first
204 206 ARGV 1-: [u'C-third']
205 207 tclass.py: deleting object: C-second
206 208 tclass.py: deleting object: C-third
207 209 """
208 210 tt.ipexec_validate(self.fname, out)
General Comments 0
You need to be logged in to leave comments. Login now