##// END OF EJS Templates
Rename misleading use of raw_input so it's not automatically converted to input by 2to3.
Thomas Kluyver -
Show More
@@ -1,658 +1,658 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2010 The IPython Development Team
6 6 #
7 7 # Distributed under the terms of the BSD License. The full license is in
8 8 # the file COPYING, distributed as part of this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14 # stdlib
15 15 import unittest
16 16 import sys
17 17
18 18 # Third party
19 19 import nose.tools as nt
20 20
21 21 # Our own
22 22 from IPython.core import inputsplitter as isp
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Semi-complete examples (also used as tests)
26 26 #-----------------------------------------------------------------------------
27 27
28 28 # Note: at the bottom, there's a slightly more complete version of this that
29 29 # can be useful during development of code here.
30 30
31 def mini_interactive_loop(raw_input):
31 def mini_interactive_loop(input_func):
32 32 """Minimal example of the logic of an interactive interpreter loop.
33 33
34 34 This serves as an example, and it is used by the test system with a fake
35 35 raw_input that simulates interactive input."""
36 36
37 37 from IPython.core.inputsplitter import InputSplitter
38 38
39 39 isp = InputSplitter()
40 40 # In practice, this input loop would be wrapped in an outside loop to read
41 41 # input indefinitely, until some exit/quit command was issued. Here we
42 42 # only illustrate the basic inner loop.
43 43 while isp.push_accepts_more():
44 44 indent = ' '*isp.indent_spaces
45 45 prompt = '>>> ' + indent
46 line = indent + raw_input(prompt)
46 line = indent + input_func(prompt)
47 47 isp.push(line)
48 48
49 49 # Here we just return input so we can use it in a test suite, but a real
50 50 # interpreter would instead send it for execution somewhere.
51 51 src = isp.source_reset()
52 52 #print 'Input source was:\n', src # dbg
53 53 return src
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Test utilities, just for local use
57 57 #-----------------------------------------------------------------------------
58 58
59 59 def assemble(block):
60 60 """Assemble a block into multi-line sub-blocks."""
61 61 return ['\n'.join(sub_block)+'\n' for sub_block in block]
62 62
63 63
64 64 def pseudo_input(lines):
65 65 """Return a function that acts like raw_input but feeds the input list."""
66 66 ilines = iter(lines)
67 67 def raw_in(prompt):
68 68 try:
69 69 return next(ilines)
70 70 except StopIteration:
71 71 return ''
72 72 return raw_in
73 73
74 74 #-----------------------------------------------------------------------------
75 75 # Tests
76 76 #-----------------------------------------------------------------------------
77 77 def test_spaces():
78 78 tests = [('', 0),
79 79 (' ', 1),
80 80 ('\n', 0),
81 81 (' \n', 1),
82 82 ('x', 0),
83 83 (' x', 1),
84 84 (' x',2),
85 85 (' x',4),
86 86 # Note: tabs are counted as a single whitespace!
87 87 ('\tx', 1),
88 88 ('\t x', 2),
89 89 ]
90 90
91 91 for s, nsp in tests:
92 92 nt.assert_equal(isp.num_ini_spaces(s), nsp)
93 93
94 94
95 95 def test_remove_comments():
96 96 tests = [('text', 'text'),
97 97 ('text # comment', 'text '),
98 98 ('text # comment\n', 'text \n'),
99 99 ('text # comment \n', 'text \n'),
100 100 ('line # c \nline\n','line \nline\n'),
101 101 ('line # c \nline#c2 \nline\nline #c\n\n',
102 102 'line \nline\nline\nline \n\n'),
103 103 ]
104 104
105 105 for inp, out in tests:
106 106 nt.assert_equal(isp.remove_comments(inp), out)
107 107
108 108
109 109 def test_get_input_encoding():
110 110 encoding = isp.get_input_encoding()
111 111 nt.assert_true(isinstance(encoding, basestring))
112 112 # simple-minded check that at least encoding a simple string works with the
113 113 # encoding we got.
114 114 nt.assert_equal('test'.encode(encoding), 'test')
115 115
116 116
117 117 class NoInputEncodingTestCase(unittest.TestCase):
118 118 def setUp(self):
119 119 self.old_stdin = sys.stdin
120 120 class X: pass
121 121 fake_stdin = X()
122 122 sys.stdin = fake_stdin
123 123
124 124 def test(self):
125 125 # Verify that if sys.stdin has no 'encoding' attribute we do the right
126 126 # thing
127 127 enc = isp.get_input_encoding()
128 128 self.assertEqual(enc, 'ascii')
129 129
130 130 def tearDown(self):
131 131 sys.stdin = self.old_stdin
132 132
133 133
134 134 class InputSplitterTestCase(unittest.TestCase):
135 135 def setUp(self):
136 136 self.isp = isp.InputSplitter()
137 137
138 138 def test_reset(self):
139 139 isp = self.isp
140 140 isp.push('x=1')
141 141 isp.reset()
142 142 self.assertEqual(isp._buffer, [])
143 143 self.assertEqual(isp.indent_spaces, 0)
144 144 self.assertEqual(isp.source, '')
145 145 self.assertEqual(isp.code, None)
146 146 self.assertEqual(isp._is_complete, False)
147 147
148 148 def test_source(self):
149 149 self.isp._store('1')
150 150 self.isp._store('2')
151 151 self.assertEqual(self.isp.source, '1\n2\n')
152 152 self.assertTrue(len(self.isp._buffer)>0)
153 153 self.assertEqual(self.isp.source_reset(), '1\n2\n')
154 154 self.assertEqual(self.isp._buffer, [])
155 155 self.assertEqual(self.isp.source, '')
156 156
157 157 def test_indent(self):
158 158 isp = self.isp # shorthand
159 159 isp.push('x=1')
160 160 self.assertEqual(isp.indent_spaces, 0)
161 161 isp.push('if 1:\n x=1')
162 162 self.assertEqual(isp.indent_spaces, 4)
163 163 isp.push('y=2\n')
164 164 self.assertEqual(isp.indent_spaces, 0)
165 165 isp.push('if 1:')
166 166 self.assertEqual(isp.indent_spaces, 4)
167 167 isp.push(' x=1')
168 168 self.assertEqual(isp.indent_spaces, 4)
169 169 # Blank lines shouldn't change the indent level
170 170 isp.push(' '*2)
171 171 self.assertEqual(isp.indent_spaces, 4)
172 172
173 173 def test_indent2(self):
174 174 isp = self.isp
175 175 # When a multiline statement contains parens or multiline strings, we
176 176 # shouldn't get confused.
177 177 isp.push("if 1:")
178 178 isp.push(" x = (1+\n 2)")
179 179 self.assertEqual(isp.indent_spaces, 4)
180 180
181 181 def test_dedent(self):
182 182 isp = self.isp # shorthand
183 183 isp.push('if 1:')
184 184 self.assertEqual(isp.indent_spaces, 4)
185 185 isp.push(' pass')
186 186 self.assertEqual(isp.indent_spaces, 0)
187 187
188 188 def test_push(self):
189 189 isp = self.isp
190 190 self.assertTrue(isp.push('x=1'))
191 191
192 192 def test_push2(self):
193 193 isp = self.isp
194 194 self.assertFalse(isp.push('if 1:'))
195 195 for line in [' x=1', '# a comment', ' y=2']:
196 196 self.assertTrue(isp.push(line))
197 197
198 198 def test_push3(self):
199 199 """Test input with leading whitespace"""
200 200 isp = self.isp
201 201 isp.push(' x=1')
202 202 isp.push(' y=2')
203 203 self.assertEqual(isp.source, 'if 1:\n x=1\n y=2\n')
204 204
205 205 def test_replace_mode(self):
206 206 isp = self.isp
207 207 isp.input_mode = 'cell'
208 208 isp.push('x=1')
209 209 self.assertEqual(isp.source, 'x=1\n')
210 210 isp.push('x=2')
211 211 self.assertEqual(isp.source, 'x=2\n')
212 212
213 213 def test_push_accepts_more(self):
214 214 isp = self.isp
215 215 isp.push('x=1')
216 216 self.assertFalse(isp.push_accepts_more())
217 217
218 218 def test_push_accepts_more2(self):
219 219 isp = self.isp
220 220 isp.push('if 1:')
221 221 self.assertTrue(isp.push_accepts_more())
222 222 isp.push(' x=1')
223 223 self.assertTrue(isp.push_accepts_more())
224 224 isp.push('')
225 225 self.assertFalse(isp.push_accepts_more())
226 226
227 227 def test_push_accepts_more3(self):
228 228 isp = self.isp
229 229 isp.push("x = (2+\n3)")
230 230 self.assertFalse(isp.push_accepts_more())
231 231
232 232 def test_push_accepts_more4(self):
233 233 isp = self.isp
234 234 # When a multiline statement contains parens or multiline strings, we
235 235 # shouldn't get confused.
236 236 # FIXME: we should be able to better handle de-dents in statements like
237 237 # multiline strings and multiline expressions (continued with \ or
238 238 # parens). Right now we aren't handling the indentation tracking quite
239 239 # correctly with this, though in practice it may not be too much of a
240 240 # problem. We'll need to see.
241 241 isp.push("if 1:")
242 242 isp.push(" x = (2+")
243 243 isp.push(" 3)")
244 244 self.assertTrue(isp.push_accepts_more())
245 245 isp.push(" y = 3")
246 246 self.assertTrue(isp.push_accepts_more())
247 247 isp.push('')
248 248 self.assertFalse(isp.push_accepts_more())
249 249
250 250 def test_continuation(self):
251 251 isp = self.isp
252 252 isp.push("import os, \\")
253 253 self.assertTrue(isp.push_accepts_more())
254 254 isp.push("sys")
255 255 self.assertFalse(isp.push_accepts_more())
256 256
257 257 def test_syntax_error(self):
258 258 isp = self.isp
259 259 # Syntax errors immediately produce a 'ready' block, so the invalid
260 260 # Python can be sent to the kernel for evaluation with possible ipython
261 261 # special-syntax conversion.
262 262 isp.push('run foo')
263 263 self.assertFalse(isp.push_accepts_more())
264 264
265 265 def check_split(self, block_lines, compile=True):
266 266 blocks = assemble(block_lines)
267 267 lines = ''.join(blocks)
268 268 oblock = self.isp.split_blocks(lines)
269 269 self.assertEqual(oblock, blocks)
270 270 if compile:
271 271 for block in blocks:
272 272 self.isp._compile(block)
273 273
274 274 def test_split(self):
275 275 # All blocks of input we want to test in a list. The format for each
276 276 # block is a list of lists, with each inner lists consisting of all the
277 277 # lines (as single-lines) that should make up a sub-block.
278 278
279 279 # Note: do NOT put here sub-blocks that don't compile, as the
280 280 # check_split() routine makes a final verification pass to check that
281 281 # each sub_block, as returned by split_blocks(), does compile
282 282 # correctly.
283 283 all_blocks = [ [['x=1']],
284 284
285 285 [['x=1'],
286 286 ['y=2']],
287 287
288 288 [['x=1',
289 289 '# a comment'],
290 290 ['y=11']],
291 291
292 292 [['if 1:',
293 293 ' x=1'],
294 294 ['y=3']],
295 295
296 296 [['def f(x):',
297 297 ' return x'],
298 298 ['x=1']],
299 299
300 300 [['def f(x):',
301 301 ' x+=1',
302 302 ' ',
303 303 ' return x'],
304 304 ['x=1']],
305 305
306 306 [['def f(x):',
307 307 ' if x>0:',
308 308 ' y=1',
309 309 ' # a comment',
310 310 ' else:',
311 311 ' y=4',
312 312 ' ',
313 313 ' return y'],
314 314 ['x=1'],
315 315 ['if 1:',
316 316 ' y=11'] ],
317 317
318 318 [['for i in range(10):'
319 319 ' x=i**2']],
320 320
321 321 [['for i in range(10):'
322 322 ' x=i**2'],
323 323 ['z = 1']],
324 324 ]
325 325 for block_lines in all_blocks:
326 326 self.check_split(block_lines)
327 327
328 328 def test_split_syntax_errors(self):
329 329 # Block splitting with invalid syntax
330 330 all_blocks = [ [['a syntax error']],
331 331
332 332 [['x=1',
333 333 'another syntax error']],
334 334
335 335 [['for i in range(10):'
336 336 ' yet another error']],
337 337
338 338 ]
339 339 for block_lines in all_blocks:
340 340 self.check_split(block_lines, compile=False)
341 341
342 342
343 343 class InteractiveLoopTestCase(unittest.TestCase):
344 344 """Tests for an interactive loop like a python shell.
345 345 """
346 346 def check_ns(self, lines, ns):
347 347 """Validate that the given input lines produce the resulting namespace.
348 348
349 349 Note: the input lines are given exactly as they would be typed in an
350 350 auto-indenting environment, as mini_interactive_loop above already does
351 351 auto-indenting and prepends spaces to the input.
352 352 """
353 353 src = mini_interactive_loop(pseudo_input(lines))
354 354 test_ns = {}
355 355 exec src in test_ns
356 356 # We can't check that the provided ns is identical to the test_ns,
357 357 # because Python fills test_ns with extra keys (copyright, etc). But
358 358 # we can check that the given dict is *contained* in test_ns
359 359 for k,v in ns.iteritems():
360 360 self.assertEqual(test_ns[k], v)
361 361
362 362 def test_simple(self):
363 363 self.check_ns(['x=1'], dict(x=1))
364 364
365 365 def test_simple2(self):
366 366 self.check_ns(['if 1:', 'x=2'], dict(x=2))
367 367
368 368 def test_xy(self):
369 369 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
370 370
371 371 def test_abc(self):
372 372 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
373 373
374 374 def test_multi(self):
375 375 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
376 376
377 377
378 378 def test_LineInfo():
379 379 """Simple test for LineInfo construction and str()"""
380 380 linfo = isp.LineInfo(' %cd /home')
381 381 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
382 382
383 383
384 384 def test_split_user_input():
385 385 """Unicode test - split_user_input already has good doctests"""
386 386 line = u"PΓ©rez Fernando"
387 387 parts = isp.split_user_input(line)
388 388 parts_expected = (u'', u'', u'', line)
389 389 nt.assert_equal(parts, parts_expected)
390 390
391 391
392 392 # Transformer tests
393 393 def transform_checker(tests, func):
394 394 """Utility to loop over test inputs"""
395 395 for inp, tr in tests:
396 396 nt.assert_equals(func(inp), tr)
397 397
398 398 # Data for all the syntax tests in the form of lists of pairs of
399 399 # raw/transformed input. We store it here as a global dict so that we can use
400 400 # it both within single-function tests and also to validate the behavior of the
401 401 # larger objects
402 402
403 403 syntax = \
404 404 dict(assign_system =
405 405 [('a =! ls', 'a = get_ipython().getoutput("ls")'),
406 406 ('b = !ls', 'b = get_ipython().getoutput("ls")'),
407 407 ('x=1', 'x=1'), # normal input is unmodified
408 408 (' ',' '), # blank lines are kept intact
409 409 ],
410 410
411 411 assign_magic =
412 412 [('a =% who', 'a = get_ipython().magic("who")'),
413 413 ('b = %who', 'b = get_ipython().magic("who")'),
414 414 ('x=1', 'x=1'), # normal input is unmodified
415 415 (' ',' '), # blank lines are kept intact
416 416 ],
417 417
418 418 classic_prompt =
419 419 [('>>> x=1', 'x=1'),
420 420 ('x=1', 'x=1'), # normal input is unmodified
421 421 (' ', ' '), # blank lines are kept intact
422 422 ('... ', ''), # continuation prompts
423 423 ],
424 424
425 425 ipy_prompt =
426 426 [('In [1]: x=1', 'x=1'),
427 427 ('x=1', 'x=1'), # normal input is unmodified
428 428 (' ',' '), # blank lines are kept intact
429 429 (' ....: ', ''), # continuation prompts
430 430 ],
431 431
432 432 # Tests for the escape transformer to leave normal code alone
433 433 escaped_noesc =
434 434 [ (' ', ' '),
435 435 ('x=1', 'x=1'),
436 436 ],
437 437
438 438 # System calls
439 439 escaped_shell =
440 440 [ ('!ls', 'get_ipython().system("ls")'),
441 441 # Double-escape shell, this means to capture the output of the
442 442 # subprocess and return it
443 443 ('!!ls', 'get_ipython().getoutput("ls")'),
444 444 ],
445 445
446 446 # Help/object info
447 447 escaped_help =
448 448 [ ('?', 'get_ipython().show_usage()'),
449 449 ('?x1', 'get_ipython().magic("pinfo x1")'),
450 450 ('??x2', 'get_ipython().magic("pinfo2 x2")'),
451 451 ('x3?', 'get_ipython().magic("pinfo x3")'),
452 452 ('x4??', 'get_ipython().magic("pinfo2 x4")'),
453 453 ('%hist?', 'get_ipython().magic("pinfo %hist")'),
454 454 ('f*?', 'get_ipython().magic("psearch f*")'),
455 455 ('ax.*aspe*?', 'get_ipython().magic("psearch ax.*aspe*")'),
456 456 ],
457 457
458 458 # Explicit magic calls
459 459 escaped_magic =
460 460 [ ('%cd', 'get_ipython().magic("cd")'),
461 461 ('%cd /home', 'get_ipython().magic("cd /home")'),
462 462 (' %magic', ' get_ipython().magic("magic")'),
463 463 ],
464 464
465 465 # Quoting with separate arguments
466 466 escaped_quote =
467 467 [ (',f', 'f("")'),
468 468 (',f x', 'f("x")'),
469 469 (' ,f y', ' f("y")'),
470 470 (',f a b', 'f("a", "b")'),
471 471 ],
472 472
473 473 # Quoting with single argument
474 474 escaped_quote2 =
475 475 [ (';f', 'f("")'),
476 476 (';f x', 'f("x")'),
477 477 (' ;f y', ' f("y")'),
478 478 (';f a b', 'f("a b")'),
479 479 ],
480 480
481 481 # Simply apply parens
482 482 escaped_paren =
483 483 [ ('/f', 'f()'),
484 484 ('/f x', 'f(x)'),
485 485 (' /f y', ' f(y)'),
486 486 ('/f a b', 'f(a, b)'),
487 487 ],
488 488
489 489 )
490 490
491 491 # multiline syntax examples. Each of these should be a list of lists, with
492 492 # each entry itself having pairs of raw/transformed input. The union (with
493 493 # '\n'.join() of the transformed inputs is what the splitter should produce
494 494 # when fed the raw lines one at a time via push.
495 495 syntax_ml = \
496 496 dict(classic_prompt =
497 497 [ [('>>> for i in range(10):','for i in range(10):'),
498 498 ('... print i',' print i'),
499 499 ('... ', ''),
500 500 ],
501 501 ],
502 502
503 503 ipy_prompt =
504 504 [ [('In [24]: for i in range(10):','for i in range(10):'),
505 505 (' ....: print i',' print i'),
506 506 (' ....: ', ''),
507 507 ],
508 508 ],
509 509 )
510 510
511 511
512 512 def test_assign_system():
513 513 transform_checker(syntax['assign_system'], isp.transform_assign_system)
514 514
515 515
516 516 def test_assign_magic():
517 517 transform_checker(syntax['assign_magic'], isp.transform_assign_magic)
518 518
519 519
520 520 def test_classic_prompt():
521 521 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
522 522 for example in syntax_ml['classic_prompt']:
523 523 transform_checker(example, isp.transform_classic_prompt)
524 524
525 525
526 526 def test_ipy_prompt():
527 527 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
528 528 for example in syntax_ml['ipy_prompt']:
529 529 transform_checker(example, isp.transform_ipy_prompt)
530 530
531 531
532 532 def test_escaped_noesc():
533 533 transform_checker(syntax['escaped_noesc'], isp.transform_escaped)
534 534
535 535
536 536 def test_escaped_shell():
537 537 transform_checker(syntax['escaped_shell'], isp.transform_escaped)
538 538
539 539
540 540 def test_escaped_help():
541 541 transform_checker(syntax['escaped_help'], isp.transform_escaped)
542 542
543 543
544 544 def test_escaped_magic():
545 545 transform_checker(syntax['escaped_magic'], isp.transform_escaped)
546 546
547 547
548 548 def test_escaped_quote():
549 549 transform_checker(syntax['escaped_quote'], isp.transform_escaped)
550 550
551 551
552 552 def test_escaped_quote2():
553 553 transform_checker(syntax['escaped_quote2'], isp.transform_escaped)
554 554
555 555
556 556 def test_escaped_paren():
557 557 transform_checker(syntax['escaped_paren'], isp.transform_escaped)
558 558
559 559
560 560 class IPythonInputTestCase(InputSplitterTestCase):
561 561 """By just creating a new class whose .isp is a different instance, we
562 562 re-run the same test battery on the new input splitter.
563 563
564 564 In addition, this runs the tests over the syntax and syntax_ml dicts that
565 565 were tested by individual functions, as part of the OO interface.
566 566 """
567 567
568 568 def setUp(self):
569 569 self.isp = isp.IPythonInputSplitter(input_mode='line')
570 570
571 571 def test_syntax(self):
572 572 """Call all single-line syntax tests from the main object"""
573 573 isp = self.isp
574 574 for example in syntax.itervalues():
575 575 for raw, out_t in example:
576 576 if raw.startswith(' '):
577 577 continue
578 578
579 579 isp.push(raw)
580 580 out = isp.source_reset().rstrip()
581 581 self.assertEqual(out, out_t)
582 582
583 583 def test_syntax_multiline(self):
584 584 isp = self.isp
585 585 for example in syntax_ml.itervalues():
586 586 out_t_parts = []
587 587 for line_pairs in example:
588 588 for raw, out_t_part in line_pairs:
589 589 isp.push(raw)
590 590 out_t_parts.append(out_t_part)
591 591
592 592 out = isp.source_reset().rstrip()
593 593 out_t = '\n'.join(out_t_parts).rstrip()
594 594 self.assertEqual(out, out_t)
595 595
596 596
597 597 class BlockIPythonInputTestCase(IPythonInputTestCase):
598 598
599 599 # Deactivate tests that don't make sense for the block mode
600 600 test_push3 = test_split = lambda s: None
601 601
602 602 def setUp(self):
603 603 self.isp = isp.IPythonInputSplitter(input_mode='cell')
604 604
605 605 def test_syntax_multiline(self):
606 606 isp = self.isp
607 607 for example in syntax_ml.itervalues():
608 608 raw_parts = []
609 609 out_t_parts = []
610 610 for line_pairs in example:
611 611 for raw, out_t_part in line_pairs:
612 612 raw_parts.append(raw)
613 613 out_t_parts.append(out_t_part)
614 614
615 615 raw = '\n'.join(raw_parts)
616 616 out_t = '\n'.join(out_t_parts)
617 617
618 618 isp.push(raw)
619 619 out = isp.source_reset()
620 620 # Match ignoring trailing whitespace
621 621 self.assertEqual(out.rstrip(), out_t.rstrip())
622 622
623 623
624 624 #-----------------------------------------------------------------------------
625 625 # Main - use as a script, mostly for developer experiments
626 626 #-----------------------------------------------------------------------------
627 627
628 628 if __name__ == '__main__':
629 629 # A simple demo for interactive experimentation. This code will not get
630 630 # picked up by any test suite.
631 631 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
632 632
633 633 # configure here the syntax to use, prompt and whether to autoindent
634 634 #isp, start_prompt = InputSplitter(), '>>> '
635 635 isp, start_prompt = IPythonInputSplitter(), 'In> '
636 636
637 637 autoindent = True
638 638 #autoindent = False
639 639
640 640 try:
641 641 while True:
642 642 prompt = start_prompt
643 643 while isp.push_accepts_more():
644 644 indent = ' '*isp.indent_spaces
645 645 if autoindent:
646 646 line = indent + raw_input(prompt+indent)
647 647 else:
648 648 line = raw_input(prompt)
649 649 isp.push(line)
650 650 prompt = '... '
651 651
652 652 # Here we just return input so we can use it in a test suite, but a
653 653 # real interpreter would instead send it for execution somewhere.
654 654 #src = isp.source; raise EOFError # dbg
655 655 src = isp.source_reset()
656 656 print 'Input source was:\n', src
657 657 except EOFError:
658 658 print 'Bye'
General Comments 0
You need to be logged in to leave comments. Login now