Show More
@@ -141,6 +141,7 b' def num_ini_spaces(s):' | |||
|
141 | 141 | else: |
|
142 | 142 | return 0 |
|
143 | 143 | |
|
144 | last_blank_re = re.compile(r'^.*\n\s+$', re.MULTILINE) | |
|
144 | 145 | |
|
145 | 146 | def last_blank(src): |
|
146 | 147 | """Determine if the input source ends in a blank. |
@@ -152,9 +153,22 b' def last_blank(src):' | |||
|
152 | 153 | src : string |
|
153 | 154 | A single or multiline string. |
|
154 | 155 | """ |
|
155 | if not src: return False | |
|
156 | ll = src.splitlines()[-1] | |
|
157 | return (ll == '') or ll.isspace() | |
|
156 | return src == '\n' or bool(last_blank_re.match(src)) | |
|
157 | ||
|
158 | ||
|
159 | last_two_blanks_re = re.compile(r'^.*\n\s*\n\s*$', re.MULTILINE) | |
|
160 | ||
|
161 | def last_two_blanks(src): | |
|
162 | """Determine if the input source ends in two blanks. | |
|
163 | ||
|
164 | A blank is either a newline or a line consisting of whitespace. | |
|
165 | ||
|
166 | Parameters | |
|
167 | ---------- | |
|
168 | src : string | |
|
169 | A single or multiline string. | |
|
170 | """ | |
|
171 | return bool(last_two_blanks_re.match(src)) | |
|
158 | 172 | |
|
159 | 173 | |
|
160 | 174 | def remove_comments(src): |
@@ -820,6 +834,76 b' class IPythonInputSplitter(InputSplitter):' | |||
|
820 | 834 | out = push(line) |
|
821 | 835 | return out |
|
822 | 836 | |
|
837 | ||
|
838 | def _push_cell_mode(self, lines): | |
|
839 | """Push in cell mode. | |
|
840 | ||
|
841 | This means that we get the entire cell with each call. Between resets, | |
|
842 | the calls simply add more text to the input.""" | |
|
843 | ||
|
844 | if lines.startswith('%%'): | |
|
845 | # Cell magics bypass all further transformations | |
|
846 | self.cell_magic_mode = True | |
|
847 | first, _, body = lines.partition('\n') | |
|
848 | magic_name, _, line = first.partition(' ') | |
|
849 | magic_name = magic_name.lstrip(ESC_MAGIC) | |
|
850 | # We store the body of the cell and create a call to a method that | |
|
851 | # will use this stored value. This is ugly, but it's a first cut to | |
|
852 | # get it all working, as right now changing the return API of our | |
|
853 | # methods would require major refactoring. | |
|
854 | self.cell_magic_parts = [body] | |
|
855 | tpl = 'get_ipython()._cell_magic(%r, %r)' | |
|
856 | tlines = tpl % (magic_name, line) | |
|
857 | self._store(tlines) | |
|
858 | self._store(lines, self._buffer_raw, 'source_raw') | |
|
859 | self._is_complete = last_two_blanks(lines) | |
|
860 | return self._is_complete | |
|
861 | ||
|
862 | lines_list = lines.splitlines() | |
|
863 | ||
|
864 | transforms = [transform_ipy_prompt, transform_classic_prompt, | |
|
865 | transform_help_end, transform_escaped, | |
|
866 | transform_assign_system, transform_assign_magic] | |
|
867 | ||
|
868 | # Transform logic | |
|
869 | # | |
|
870 | # We only apply the line transformers to the input if we have either no | |
|
871 | # input yet, or complete input, or if the last line of the buffer ends | |
|
872 | # with ':' (opening an indented block). This prevents the accidental | |
|
873 | # transformation of escapes inside multiline expressions like | |
|
874 | # triple-quoted strings or parenthesized expressions. | |
|
875 | # | |
|
876 | # The last heuristic, while ugly, ensures that the first line of an | |
|
877 | # indented block is correctly transformed. | |
|
878 | # | |
|
879 | # FIXME: try to find a cleaner approach for this last bit. | |
|
880 | ||
|
881 | # In cell mode, since we're going to pump the parent class by hand line | |
|
882 | # by line, we need to temporarily switch out to 'line' mode, do a | |
|
883 | # single manual reset and then feed the lines one by one. Note that | |
|
884 | # this only matters if the input has more than one line. | |
|
885 | self.reset() | |
|
886 | self.input_mode = 'line' | |
|
887 | ||
|
888 | # Store raw source before applying any transformations to it. Note | |
|
889 | # that this must be done *after* the reset() call that would otherwise | |
|
890 | # flush the buffer. | |
|
891 | self._store(lines, self._buffer_raw, 'source_raw') | |
|
892 | ||
|
893 | try: | |
|
894 | push = super(IPythonInputSplitter, self).push | |
|
895 | buf = self._buffer | |
|
896 | for line in lines_list: | |
|
897 | if self._is_complete or not buf or \ | |
|
898 | (buf and buf[-1].rstrip().endswith((':', ','))): | |
|
899 | for f in transforms: | |
|
900 | line = f(line) | |
|
901 | ||
|
902 | out = push(line) | |
|
903 | finally: | |
|
904 | self.input_mode = 'cell' | |
|
905 | return out | |
|
906 | ||
|
823 | 907 | def push(self, lines): |
|
824 | 908 | """Push one or more lines of IPython input. |
|
825 | 909 | |
@@ -843,8 +927,6 b' class IPythonInputSplitter(InputSplitter):' | |||
|
843 | 927 | this value is also stored as a private attribute (_is_complete), so it |
|
844 | 928 | can be queried at any time. |
|
845 | 929 | """ |
|
846 | print('mode:', self.input_mode) | |
|
847 | print('lines:',repr(lines)) | |
|
848 | 930 | if not lines: |
|
849 | 931 | return super(IPythonInputSplitter, self).push(lines) |
|
850 | 932 | |
@@ -853,9 +935,8 b' class IPythonInputSplitter(InputSplitter):' | |||
|
853 | 935 | |
|
854 | 936 | if self.input_mode == 'line': |
|
855 | 937 | return self._push_line_mode(lines) |
|
856 | ||
|
857 | ## else: | |
|
858 | ## return self._push_cell_mode(lines) | |
|
938 | else: | |
|
939 | return self._push_cell_mode(lines) | |
|
859 | 940 | |
|
860 | 941 | lines_list = lines.splitlines() |
|
861 | 942 |
@@ -604,12 +604,27 b' def test_last_blank():' | |||
|
604 | 604 | nt.assert_false(isp.last_blank('abc')) |
|
605 | 605 | nt.assert_false(isp.last_blank('abc\n')) |
|
606 | 606 | nt.assert_false(isp.last_blank('abc\na')) |
|
607 | ||
|
607 | 608 | nt.assert_true(isp.last_blank('\n')) |
|
608 | 609 | nt.assert_true(isp.last_blank('\n ')) |
|
609 | 610 | nt.assert_true(isp.last_blank('abc\n ')) |
|
610 | 611 | nt.assert_true(isp.last_blank('abc\n\n')) |
|
611 | 612 | |
|
612 | 613 | |
|
614 | def test_last_two_blanks(): | |
|
615 | nt.assert_false(isp.last_two_blanks('')) | |
|
616 | nt.assert_false(isp.last_two_blanks('abc')) | |
|
617 | nt.assert_false(isp.last_two_blanks('abc\n')) | |
|
618 | nt.assert_false(isp.last_two_blanks('abc\n\na')) | |
|
619 | ||
|
620 | nt.assert_true(isp.last_two_blanks('\n\n')) | |
|
621 | nt.assert_true(isp.last_two_blanks('\n\n ')) | |
|
622 | nt.assert_true(isp.last_two_blanks('\n \n')) | |
|
623 | nt.assert_true(isp.last_two_blanks('abc\n \n')) | |
|
624 | nt.assert_true(isp.last_two_blanks('abc\n\n ')) | |
|
625 | nt.assert_true(isp.last_two_blanks('abc\n\n')) | |
|
626 | ||
|
627 | ||
|
613 | 628 | def test_cell_magics(): |
|
614 | 629 | from IPython.core import magic |
|
615 | 630 |
General Comments 0
You need to be logged in to leave comments.
Login now