##// END OF EJS Templates
Merge pull request #2110 from asmeurer/inputsplitter...
Fernando Perez -
r7827:c7401c9b merge
parent child Browse files
Show More
@@ -115,7 +115,9 b" dedent_re = re.compile('|'.join(["
115 115 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
116 116 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
117 117 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
118 r'^\s+pass\s*$' # pass (optionally followed by trailing spaces)
118 r'^\s+pass\s*$', # pass (optionally followed by trailing spaces)
119 r'^\s+break\s*$', # break (optionally followed by trailing spaces)
120 r'^\s+continue\s*$', # continue (optionally followed by trailing spaces)
119 121 ]))
120 122 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
121 123
@@ -202,17 +204,17 b' def remove_comments(src):'
202 204 """
203 205
204 206 return re.sub('#.*', '', src)
205
207
206 208 def has_comment(src):
207 209 """Indicate whether an input line has (i.e. ends in, or is) a comment.
208
210
209 211 This uses tokenize, so it can distinguish comments from # inside strings.
210
212
211 213 Parameters
212 214 ----------
213 215 src : string
214 216 A single line input string.
215
217
216 218 Returns
217 219 -------
218 220 Boolean: True if source has a comment.
@@ -280,9 +282,9 b' class InputSplitter(object):'
280 282 code = None
281 283 # Input mode
282 284 input_mode = 'line'
283
285
284 286 # Private attributes
285
287
286 288 # List with lines of input accumulated so far
287 289 _buffer = None
288 290 # Command compiler
@@ -291,7 +293,7 b' class InputSplitter(object):'
291 293 _full_dedent = False
292 294 # Boolean indicating whether the current block is complete
293 295 _is_complete = None
294
296
295 297 def __init__(self, input_mode=None):
296 298 """Create a new InputSplitter instance.
297 299
@@ -348,7 +350,7 b' class InputSplitter(object):'
348 350 ----------
349 351 lines : string
350 352 One or more lines of Python input.
351
353
352 354 Returns
353 355 -------
354 356 is_complete : boolean
@@ -359,7 +361,7 b' class InputSplitter(object):'
359 361 """
360 362 if self.input_mode == 'cell':
361 363 self.reset()
362
364
363 365 self._store(lines)
364 366 source = self.source
365 367
@@ -369,7 +371,7 b' class InputSplitter(object):'
369 371 self.code, self._is_complete = None, None
370 372
371 373 # Honor termination lines properly
372 if source.rstrip().endswith('\\'):
374 if source.endswith('\\\n'):
373 375 return False
374 376
375 377 self._update_indent(lines)
@@ -400,11 +402,11 b' class InputSplitter(object):'
400 402 SyntaxError is raised, or *all* of the following are true:
401 403
402 404 1. The input compiles to a complete statement.
403
405
404 406 2. The indentation level is flush-left (because if we are indented,
405 407 like inside a function definition or for loop, we need to keep
406 408 reading new input).
407
409
408 410 3. There is one extra line consisting only of whitespace.
409 411
410 412 Because of condition #3, this method should be used only by
@@ -464,7 +466,7 b' class InputSplitter(object):'
464 466 ----------
465 467 line : str
466 468 A single new line of non-whitespace, non-comment Python input.
467
469
468 470 Returns
469 471 -------
470 472 indent_spaces : int
@@ -476,7 +478,7 b' class InputSplitter(object):'
476 478 """
477 479 indent_spaces = self.indent_spaces
478 480 full_dedent = self._full_dedent
479
481
480 482 inisp = num_ini_spaces(line)
481 483 if inisp < indent_spaces:
482 484 indent_spaces = inisp
@@ -495,9 +497,9 b' class InputSplitter(object):'
495 497 if indent_spaces < 0:
496 498 indent_spaces = 0
497 499 #print 'safety' # dbg
498
500
499 501 return indent_spaces, full_dedent
500
502
501 503 def _update_indent(self, lines):
502 504 for line in remove_comments(lines).splitlines():
503 505 if line and not line.isspace():
@@ -508,10 +510,10 b' class InputSplitter(object):'
508 510
509 511 If input lines are not newline-terminated, a newline is automatically
510 512 appended."""
511
513
512 514 if buffer is None:
513 515 buffer = self._buffer
514
516
515 517 if lines.endswith('\n'):
516 518 buffer.append(lines)
517 519 else:
@@ -627,10 +629,10 b' def transform_help_end(line):'
627 629 target = m.group(1)
628 630 esc = m.group(3)
629 631 lspace = _initial_space_re.match(line).group(0)
630
632
631 633 # If we're mid-command, put it back on the next prompt for the user.
632 634 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
633
635
634 636 return _make_help_call(target, esc, lspace, next_input)
635 637
636 638
@@ -647,7 +649,7 b' class EscapedTransformer(object):'
647 649 ESC_QUOTE2 : self._tr_quote2,
648 650 ESC_PAREN : self._tr_paren }
649 651 self.tr = tr
650
652
651 653 # Support for syntax transformations that use explicit escapes typed by the
652 654 # user at the beginning of a line
653 655 @staticmethod
@@ -668,7 +670,7 b' class EscapedTransformer(object):'
668 670 # A naked help line should just fire the intro help screen
669 671 if not line_info.line[1:]:
670 672 return 'get_ipython().show_usage()'
671
673
672 674 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
673 675
674 676 @staticmethod
@@ -745,7 +747,7 b' class IPythonInputSplitter(InputSplitter):'
745 747 super(IPythonInputSplitter, self).__init__(input_mode)
746 748 self._buffer_raw = []
747 749 self._validate = True
748
750
749 751 def reset(self):
750 752 """Reset the input buffer and associated state."""
751 753 super(IPythonInputSplitter, self).reset()
@@ -897,7 +899,7 b' class IPythonInputSplitter(InputSplitter):'
897 899 # that this must be done *after* the reset() call that would otherwise
898 900 # flush the buffer.
899 901 self._store(lines, self._buffer_raw, 'source_raw')
900
902
901 903 try:
902 904 push = super(IPythonInputSplitter, self).push
903 905 buf = self._buffer
@@ -227,6 +227,26 b' class InputSplitterTestCase(unittest.TestCase):'
227 227 isp.push('if 1:\n pass ')
228 228 self.assertEqual(isp.indent_spaces, 0)
229 229
230 def test_dedent_break(self):
231 isp = self.isp # shorthand
232 # should NOT cause dedent
233 isp.push('while 1:\n breaks = 5')
234 self.assertEqual(isp.indent_spaces, 4)
235 isp.push('while 1:\n break')
236 self.assertEqual(isp.indent_spaces, 0)
237 isp.push('while 1:\n break ')
238 self.assertEqual(isp.indent_spaces, 0)
239
240 def test_dedent_continue(self):
241 isp = self.isp # shorthand
242 # should NOT cause dedent
243 isp.push('while 1:\n continues = 5')
244 self.assertEqual(isp.indent_spaces, 4)
245 isp.push('while 1:\n continue')
246 self.assertEqual(isp.indent_spaces, 0)
247 isp.push('while 1:\n continue ')
248 self.assertEqual(isp.indent_spaces, 0)
249
230 250 def test_dedent_raise(self):
231 251 isp = self.isp # shorthand
232 252 # should NOT cause dedent
@@ -351,6 +371,22 b' class InputSplitterTestCase(unittest.TestCase):'
351 371 self.isp.push(u'\xc3\xa9')
352 372 self.isp.push(u"u'\xc3\xa9'")
353 373
374 def test_line_continuation(self):
375 """ Test issue #2108."""
376 isp = self.isp
377 # A blank line after a line continuation should not accept more
378 isp.push("1 \\\n\n")
379 self.assertFalse(isp.push_accepts_more())
380 # Whitespace after a \ is a SyntaxError. The only way to test that
381 # here is to test that push doesn't accept more (as with
382 # test_syntax_error() above).
383 isp.push(r"1 \ ")
384 self.assertFalse(isp.push_accepts_more())
385 # Even if the line is continuable (c.f. the regular Python
386 # interpreter)
387 isp.push(r"(1 \ ")
388 self.assertFalse(isp.push_accepts_more())
389
354 390 class InteractiveLoopTestCase(unittest.TestCase):
355 391 """Tests for an interactive loop like a python shell.
356 392 """
@@ -678,7 +714,7 b' class BlockIPythonInputTestCase(IPythonInputTestCase):'
678 714 def test_syntax_multiline_cell(self):
679 715 isp = self.isp
680 716 for example in syntax_ml.itervalues():
681
717
682 718 out_t_parts = []
683 719 for line_pairs in example:
684 720 raw = '\n'.join(r for r, _ in line_pairs)
@@ -762,7 +798,7 b' def test_last_two_blanks():'
762 798
763 799
764 800 class CellMagicsCommon(object):
765
801
766 802 def test_whole_cell(self):
767 803 src = "%%cellm line\nbody\n"
768 804 sp = self.sp
@@ -9,7 +9,7 b' Welcome to IPython. Our full documentation is available on `our website'
9 9 <http://ipython.org/documentation.html>`_; if you downloaded a built source
10 10 distribution the ``docs/source`` directory contains the plaintext version of
11 11 these manuals. If you have Sphinx installed, you can build them by typing
12 ``make html`` for local browsing.
12 ``cd docs; make html`` for local browsing.
13 13
14 14
15 15 Dependencies and supported Python versions
@@ -21,7 +21,7 b' functionality requires extra packages.'
21 21
22 22 Officially, IPython requires Python version 2.6, 2.7, or 3.1 and above.
23 23
24
24
25 25 Instant running
26 26 ===============
27 27
General Comments 0
You need to be logged in to leave comments. Login now