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