Show More
@@ -725,9 +725,13 b' class IPythonInputSplitter(InputSplitter):' | |||||
725 | # String with raw, untransformed input. |
|
725 | # String with raw, untransformed input. | |
726 | source_raw = '' |
|
726 | source_raw = '' | |
727 |
|
727 | |||
728 | cell_magic_parts = [] |
|
728 | # Flag to track when we're in the middle of processing a cell magic, since | |
|
729 | # the logic has to change. In that case, we apply no transformations at | |||
|
730 | # all. | |||
|
731 | processing_cell_magic = False | |||
729 |
|
732 | |||
730 | cell_magic_mode = False |
|
733 | # Storage for all blocks of input that make up a cell magic | |
|
734 | cell_magic_parts = [] | |||
731 |
|
735 | |||
732 | # Private attributes |
|
736 | # Private attributes | |
733 |
|
737 | |||
@@ -745,7 +749,7 b' class IPythonInputSplitter(InputSplitter):' | |||||
745 | self._buffer_raw[:] = [] |
|
749 | self._buffer_raw[:] = [] | |
746 | self.source_raw = '' |
|
750 | self.source_raw = '' | |
747 | self.cell_magic_parts = [] |
|
751 | self.cell_magic_parts = [] | |
748 |
self.cell_magic |
|
752 | self.processing_cell_magic = False | |
749 |
|
753 | |||
750 | def source_raw_reset(self): |
|
754 | def source_raw_reset(self): | |
751 | """Return input and raw source and perform a full reset. |
|
755 | """Return input and raw source and perform a full reset. | |
@@ -756,172 +760,55 b' class IPythonInputSplitter(InputSplitter):' | |||||
756 | return out, out_r |
|
760 | return out, out_r | |
757 |
|
761 | |||
758 | def push_accepts_more(self): |
|
762 | def push_accepts_more(self): | |
759 |
if self.cell_magic |
|
763 | if self.processing_cell_magic: | |
760 | return not self._is_complete |
|
764 | return not self._is_complete | |
761 | else: |
|
765 | else: | |
762 | return super(IPythonInputSplitter, self).push_accepts_more() |
|
766 | return super(IPythonInputSplitter, self).push_accepts_more() | |
763 |
|
767 | |||
764 |
def _ |
|
768 | def _handle_cell_magic(self, lines): | |
765 | """Push in line mode. |
|
769 | """Process lines when they start with %%, which marks cell magics. | |
766 |
|
||||
767 | This means that we only get individual 'lines' with each call, though |
|
|||
768 | in practice each input may be multiline. But this is in contrast to |
|
|||
769 | cell mode, which feeds the entirety of the cell from the start with |
|
|||
770 | each call. |
|
|||
771 | """ |
|
770 | """ | |
772 | # cell magic support |
|
771 | self.processing_cell_magic = True | |
773 | #print('#'*10) |
|
772 | first, _, body = lines.partition('\n') | |
774 | #print(lines+'\n---') # dbg |
|
773 | magic_name, _, line = first.partition(' ') | |
775 | #print (repr(lines)+'\n+++') |
|
774 | magic_name = magic_name.lstrip(ESC_MAGIC) | |
776 | #print('raw', self._buffer_raw, 'validate', self.cell_magic_mode) |
|
775 | # We store the body of the cell and create a call to a method that | |
777 | # Only trigger this block if we're at a 'fresh' pumping start. |
|
776 | # will use this stored value. This is ugly, but it's a first cut to | |
778 | if lines.startswith('%%'): |
|
777 | # get it all working, as right now changing the return API of our | |
779 | # Cell magics bypass all further transformations |
|
778 | # methods would require major refactoring. | |
780 |
|
|
779 | self.cell_magic_parts = [body] | |
781 | first, _, body = lines.partition('\n') |
|
780 | tpl = 'get_ipython()._cell_magic(%r, %r)' | |
782 |
magic_name, |
|
781 | tlines = tpl % (magic_name, line) | |
783 | magic_name = magic_name.lstrip(ESC_MAGIC) |
|
782 | self._store(tlines) | |
784 | # We store the body of the cell and create a call to a method that |
|
|||
785 | # will use this stored value. This is ugly, but it's a first cut to |
|
|||
786 | # get it all working, as right now changing the return API of our |
|
|||
787 | # methods would require major refactoring. |
|
|||
788 | self.cell_magic_parts = [body] |
|
|||
789 | tpl = 'get_ipython()._cell_magic(%r, %r)' |
|
|||
790 | tlines = tpl % (magic_name, line) |
|
|||
791 | self._store(tlines) |
|
|||
792 | self._store(lines, self._buffer_raw, 'source_raw') |
|
|||
793 | self._is_complete = last_two_blanks(lines) |
|
|||
794 | #print('IC', self._is_complete) # dbg |
|
|||
795 | return self._is_complete |
|
|||
796 |
|
||||
797 | if self.cell_magic_mode: |
|
|||
798 | #print('c2 lines', repr(lines)) # dbg |
|
|||
799 | # Find out if the last stored block has a whitespace line as its |
|
|||
800 | # last line and also this line is whitespace, case in which we're |
|
|||
801 | # done (two contiguous blank lines signal termination). Note that |
|
|||
802 | # the storage logic *enforces* that every stored block is |
|
|||
803 | # newline-terminated, so we grab everything but the last character |
|
|||
804 | # so we can have the body of the block alone. |
|
|||
805 | last_block = self.cell_magic_parts[-1] |
|
|||
806 | self._is_complete = last_blank(last_block) and lines.isspace() |
|
|||
807 | # Only store the raw input. For lines beyond the first one, we |
|
|||
808 | # only store them for history purposes, and for execution we want |
|
|||
809 | # the caller to only receive the _cell_magic() call. |
|
|||
810 | self._store(lines, self._buffer_raw, 'source_raw') |
|
|||
811 | self.cell_magic_parts.append(lines) |
|
|||
812 | return self._is_complete |
|
|||
813 |
|
||||
814 | lines_list = lines.splitlines() |
|
|||
815 |
|
||||
816 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
|
|||
817 | transform_help_end, transform_escaped, |
|
|||
818 | transform_assign_system, transform_assign_magic] |
|
|||
819 |
|
||||
820 | # Transform logic |
|
|||
821 | # |
|
|||
822 | # We only apply the line transformers to the input if we have either no |
|
|||
823 | # input yet, or complete input, or if the last line of the buffer ends |
|
|||
824 | # with ':' (opening an indented block). This prevents the accidental |
|
|||
825 | # transformation of escapes inside multiline expressions like |
|
|||
826 | # triple-quoted strings or parenthesized expressions. |
|
|||
827 | # |
|
|||
828 | # The last heuristic, while ugly, ensures that the first line of an |
|
|||
829 | # indented block is correctly transformed. |
|
|||
830 | # |
|
|||
831 | # FIXME: try to find a cleaner approach for this last bit. |
|
|||
832 |
|
||||
833 | # Store raw source before applying any transformations to it. Note |
|
|||
834 | # that this must be done *after* the reset() call that would otherwise |
|
|||
835 | # flush the buffer. |
|
|||
836 | self._store(lines, self._buffer_raw, 'source_raw') |
|
783 | self._store(lines, self._buffer_raw, 'source_raw') | |
|
784 | # We can actually choose whether to allow for single blank lines here | |||
|
785 | # during input for clients that use cell mode to decide when to stop | |||
|
786 | # pushing input (currently only the Qt console). | |||
|
787 | # My first implementation did that, and then I realized it wasn't | |||
|
788 | # consistent with the terminal behavior, so I've reverted it to one | |||
|
789 | # line. But I'm leaving it here so we can easily test both behaviors, | |||
|
790 | # I kind of liked having full blank lines allowed in the cell magics... | |||
|
791 | #self._is_complete = last_two_blanks(lines) | |||
|
792 | self._is_complete = last_blank(lines) | |||
|
793 | return self._is_complete | |||
837 |
|
794 | |||
838 | push = super(IPythonInputSplitter, self).push |
|
795 | def _line_mode_cell_append(self, lines): | |
839 | buf = self._buffer |
|
796 | """Append new content for a cell magic in line mode. | |
840 | for line in lines_list: |
|
797 | """ | |
841 | if self._is_complete or not buf or \ |
|
798 | # Only store the raw input. Lines beyond the first one are only only | |
842 | (buf and buf[-1].rstrip().endswith((':', ','))): |
|
799 | # stored for history purposes; for execution the caller will grab the | |
843 | for f in transforms: |
|
800 | # magic pieces from cell_magic_parts and will assemble the cell body | |
844 | line = f(line) |
|
|||
845 |
|
||||
846 | out = push(line) |
|
|||
847 | return out |
|
|||
848 |
|
||||
849 |
|
||||
850 | def _push_cell_mode(self, lines): |
|
|||
851 | """Push in cell mode. |
|
|||
852 |
|
||||
853 | This means that we get the entire cell with each call. Between resets, |
|
|||
854 | the calls simply add more text to the input.""" |
|
|||
855 | #print('lines', repr(lines)) # dbg |
|
|||
856 | if lines.startswith('%%'): |
|
|||
857 | # Cell magics bypass all further transformations |
|
|||
858 | self.cell_magic_mode = True |
|
|||
859 | first, _, body = lines.partition('\n') |
|
|||
860 | magic_name, _, line = first.partition(' ') |
|
|||
861 | magic_name = magic_name.lstrip(ESC_MAGIC) |
|
|||
862 | # We store the body of the cell and create a call to a method that |
|
|||
863 | # will use this stored value. This is ugly, but it's a first cut to |
|
|||
864 | # get it all working, as right now changing the return API of our |
|
|||
865 | # methods would require major refactoring. |
|
|||
866 | self.cell_magic_parts = [body] |
|
|||
867 | tpl = 'get_ipython()._cell_magic(%r, %r)' |
|
|||
868 | tlines = tpl % (magic_name, line) |
|
|||
869 | self._store(tlines) |
|
|||
870 | self._store(lines, self._buffer_raw, 'source_raw') |
|
|||
871 | # We can actually choose whether to allow for single blank lines |
|
|||
872 | # here.. My first implementation did that, and then I realized it |
|
|||
873 | # wasn't consistent with the console behavior, so I've reverted it |
|
|||
874 | # to one line. But I'm leaving it here so we can easily test both |
|
|||
875 | # behaviors, I kind of liked having the extra blanks be allowed in |
|
|||
876 | # the cell magics... |
|
|||
877 | #self._is_complete = last_two_blanks(lines) |
|
|||
878 | self._is_complete = last_blank(lines) |
|
|||
879 | return self._is_complete |
|
|||
880 |
|
||||
881 | lines_list = lines.splitlines() |
|
|||
882 |
|
||||
883 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
|
|||
884 | transform_help_end, transform_escaped, |
|
|||
885 | transform_assign_system, transform_assign_magic] |
|
|||
886 |
|
||||
887 | # Transform logic |
|
|||
888 | # |
|
|||
889 | # We only apply the line transformers to the input if we have either no |
|
|||
890 | # input yet, or complete input, or if the last line of the buffer ends |
|
|||
891 | # with ':' (opening an indented block). This prevents the accidental |
|
|||
892 | # transformation of escapes inside multiline expressions like |
|
|||
893 | # triple-quoted strings or parenthesized expressions. |
|
|||
894 | # |
|
|||
895 | # The last heuristic, while ugly, ensures that the first line of an |
|
|||
896 | # indented block is correctly transformed. |
|
|||
897 | # |
|
|||
898 | # FIXME: try to find a cleaner approach for this last bit. |
|
|||
899 |
|
||||
900 | # In cell mode, since we're going to pump the parent class by hand line |
|
|||
901 | # by line, we need to temporarily switch out to 'line' mode, do a |
|
|||
902 | # single manual reset and then feed the lines one by one. Note that |
|
|||
903 | # this only matters if the input has more than one line. |
|
|||
904 | self.reset() |
|
|||
905 | self.input_mode = 'line' |
|
|||
906 |
|
||||
907 | # Store raw source before applying any transformations to it. Note |
|
|||
908 | # that this must be done *after* the reset() call that would otherwise |
|
|||
909 | # flush the buffer. |
|
|||
910 | self._store(lines, self._buffer_raw, 'source_raw') |
|
801 | self._store(lines, self._buffer_raw, 'source_raw') | |
911 |
|
802 | self.cell_magic_parts.append(lines) | ||
912 | try: |
|
803 | # Find out if the last stored block has a whitespace line as its | |
913 | push = super(IPythonInputSplitter, self).push |
|
804 | # last line and also this line is whitespace, case in which we're | |
914 | buf = self._buffer |
|
805 | # done (two contiguous blank lines signal termination). Note that | |
915 | for line in lines_list: |
|
806 | # the storage logic *enforces* that every stored block is | |
916 | if self._is_complete or not buf or \ |
|
807 | # newline-terminated, so we grab everything but the last character | |
917 | (buf and buf[-1].rstrip().endswith((':', ','))): |
|
808 | # so we can have the body of the block alone. | |
918 | for f in transforms: |
|
809 | last_block = self.cell_magic_parts[-1] | |
919 | line = f(line) |
|
810 | self._is_complete = last_blank(last_block) and lines.isspace() | |
920 |
|
811 | return self._is_complete | ||
921 | out = push(line) |
|
|||
922 | finally: |
|
|||
923 | self.input_mode = 'cell' |
|
|||
924 | return out |
|
|||
925 |
|
812 | |||
926 | def push(self, lines): |
|
813 | def push(self, lines): | |
927 | """Push one or more lines of IPython input. |
|
814 | """Push one or more lines of IPython input. | |
@@ -952,11 +839,17 b' class IPythonInputSplitter(InputSplitter):' | |||||
952 | # We must ensure all input is pure unicode |
|
839 | # We must ensure all input is pure unicode | |
953 | lines = cast_unicode(lines, self.encoding) |
|
840 | lines = cast_unicode(lines, self.encoding) | |
954 |
|
841 | |||
955 | if self.input_mode == 'line': |
|
842 | # If the entire input block is a cell magic, return after handling it | |
956 | return self._push_line_mode(lines) |
|
843 | # as the rest of the transformation logic should be skipped. | |
957 | else: |
|
844 | if lines.startswith('%%'): | |
958 |
return self._ |
|
845 | return self._handle_cell_magic(lines) | |
|
846 | ||||
|
847 | # In line mode, a cell magic can arrive in separate pieces | |||
|
848 | if self.input_mode == 'line' and self.processing_cell_magic: | |||
|
849 | return self._line_mode_cell_append(lines) | |||
959 |
|
850 | |||
|
851 | # The rest of the processing is for 'normal' content, i.e. IPython | |||
|
852 | # source that we process through our transformations pipeline. | |||
960 | lines_list = lines.splitlines() |
|
853 | lines_list = lines.splitlines() | |
961 |
|
854 | |||
962 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
|
855 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
@@ -599,90 +599,6 b' def test_escaped_paren():' | |||||
599 | tt.check_pairs(isp.transform_escaped, syntax['escaped_paren']) |
|
599 | tt.check_pairs(isp.transform_escaped, syntax['escaped_paren']) | |
600 |
|
600 | |||
601 |
|
601 | |||
602 | def test_last_blank(): |
|
|||
603 | nt.assert_false(isp.last_blank('')) |
|
|||
604 | nt.assert_false(isp.last_blank('abc')) |
|
|||
605 | nt.assert_false(isp.last_blank('abc\n')) |
|
|||
606 | nt.assert_false(isp.last_blank('abc\na')) |
|
|||
607 |
|
||||
608 | nt.assert_true(isp.last_blank('\n')) |
|
|||
609 | nt.assert_true(isp.last_blank('\n ')) |
|
|||
610 | nt.assert_true(isp.last_blank('abc\n ')) |
|
|||
611 | nt.assert_true(isp.last_blank('abc\n\n')) |
|
|||
612 | nt.assert_true(isp.last_blank('abc\nd\n\n')) |
|
|||
613 | nt.assert_true(isp.last_blank('abc\nd\ne\n\n')) |
|
|||
614 | nt.assert_true(isp.last_blank('abc \n \n \n\n')) |
|
|||
615 |
|
||||
616 |
|
||||
617 | def test_last_two_blanks(): |
|
|||
618 | nt.assert_false(isp.last_two_blanks('')) |
|
|||
619 | nt.assert_false(isp.last_two_blanks('abc')) |
|
|||
620 | nt.assert_false(isp.last_two_blanks('abc\n')) |
|
|||
621 | nt.assert_false(isp.last_two_blanks('abc\n\na')) |
|
|||
622 | nt.assert_false(isp.last_two_blanks('abc\n \n')) |
|
|||
623 | nt.assert_false(isp.last_two_blanks('abc\n\n')) |
|
|||
624 |
|
||||
625 | nt.assert_true(isp.last_two_blanks('\n\n')) |
|
|||
626 | nt.assert_true(isp.last_two_blanks('\n\n ')) |
|
|||
627 | nt.assert_true(isp.last_two_blanks('\n \n')) |
|
|||
628 | nt.assert_true(isp.last_two_blanks('abc\n\n ')) |
|
|||
629 | nt.assert_true(isp.last_two_blanks('abc\n\n\n')) |
|
|||
630 | nt.assert_true(isp.last_two_blanks('abc\n\n \n')) |
|
|||
631 | nt.assert_true(isp.last_two_blanks('abc\n\n \n ')) |
|
|||
632 | nt.assert_true(isp.last_two_blanks('abc\n\n \n \n')) |
|
|||
633 | nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n')) |
|
|||
634 | nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n')) |
|
|||
635 |
|
||||
636 |
|
||||
637 | def test_cell_magics_line_mode(): |
|
|||
638 |
|
||||
639 | cell = """\ |
|
|||
640 | %%cellm line |
|
|||
641 | body |
|
|||
642 | """ |
|
|||
643 | sp = isp.IPythonInputSplitter(input_mode='line') |
|
|||
644 | sp.push(cell) |
|
|||
645 | nt.assert_equal(sp.cell_magic_parts, ['body\n']) |
|
|||
646 | out = sp.source |
|
|||
647 | ref = u"get_ipython()._cell_magic(u'cellm', u'line')\n" |
|
|||
648 | nt.assert_equal(out, ref) |
|
|||
649 |
|
||||
650 | sp.reset() |
|
|||
651 |
|
||||
652 | sp.push('%%cellm line2\n') |
|
|||
653 | nt.assert_true(sp.push_accepts_more()) #1 |
|
|||
654 | sp.push('\n') |
|
|||
655 | nt.assert_true(sp.push_accepts_more()) #2 |
|
|||
656 | sp.push('\n') |
|
|||
657 | nt.assert_false(sp.push_accepts_more()) #3 |
|
|||
658 |
|
||||
659 |
|
||||
660 | def test_cell_magics_cell_mode(): |
|
|||
661 |
|
||||
662 | cell = """\ |
|
|||
663 | %%cellm line |
|
|||
664 | body |
|
|||
665 | """ |
|
|||
666 | sp = isp.IPythonInputSplitter(input_mode='cell') |
|
|||
667 | sp.push(cell) |
|
|||
668 | nt.assert_equal(sp.cell_magic_parts, ['body\n']) |
|
|||
669 | out = sp.source |
|
|||
670 | ref = u"get_ipython()._cell_magic(u'cellm', u'line')\n" |
|
|||
671 | nt.assert_equal(out, ref) |
|
|||
672 |
|
||||
673 | sp.reset() |
|
|||
674 |
|
||||
675 | src = '%%cellm line2\n' |
|
|||
676 | sp.push(src) |
|
|||
677 | nt.assert_true(sp.push_accepts_more()) #1 |
|
|||
678 | src += '\n' |
|
|||
679 | sp.push(src) |
|
|||
680 | nt.assert_true(sp.push_accepts_more()) #2 |
|
|||
681 | src += '\n' |
|
|||
682 | sp.push(src) |
|
|||
683 | nt.assert_false(sp.push_accepts_more()) #3 |
|
|||
684 |
|
||||
685 |
|
||||
686 | class IPythonInputTestCase(InputSplitterTestCase): |
|
602 | class IPythonInputTestCase(InputSplitterTestCase): | |
687 | """By just creating a new class whose .isp is a different instance, we |
|
603 | """By just creating a new class whose .isp is a different instance, we | |
688 | re-run the same test battery on the new input splitter. |
|
604 | re-run the same test battery on the new input splitter. | |
@@ -792,3 +708,96 b" if __name__ == '__main__':" | |||||
792 | print 'Raw source was:\n', raw |
|
708 | print 'Raw source was:\n', raw | |
793 | except EOFError: |
|
709 | except EOFError: | |
794 | print 'Bye' |
|
710 | print 'Bye' | |
|
711 | ||||
|
712 | # Tests for cell magics support | |||
|
713 | ||||
|
714 | def test_last_blank(): | |||
|
715 | nt.assert_false(isp.last_blank('')) | |||
|
716 | nt.assert_false(isp.last_blank('abc')) | |||
|
717 | nt.assert_false(isp.last_blank('abc\n')) | |||
|
718 | nt.assert_false(isp.last_blank('abc\na')) | |||
|
719 | ||||
|
720 | nt.assert_true(isp.last_blank('\n')) | |||
|
721 | nt.assert_true(isp.last_blank('\n ')) | |||
|
722 | nt.assert_true(isp.last_blank('abc\n ')) | |||
|
723 | nt.assert_true(isp.last_blank('abc\n\n')) | |||
|
724 | nt.assert_true(isp.last_blank('abc\nd\n\n')) | |||
|
725 | nt.assert_true(isp.last_blank('abc\nd\ne\n\n')) | |||
|
726 | nt.assert_true(isp.last_blank('abc \n \n \n\n')) | |||
|
727 | ||||
|
728 | ||||
|
729 | def test_last_two_blanks(): | |||
|
730 | nt.assert_false(isp.last_two_blanks('')) | |||
|
731 | nt.assert_false(isp.last_two_blanks('abc')) | |||
|
732 | nt.assert_false(isp.last_two_blanks('abc\n')) | |||
|
733 | nt.assert_false(isp.last_two_blanks('abc\n\na')) | |||
|
734 | nt.assert_false(isp.last_two_blanks('abc\n \n')) | |||
|
735 | nt.assert_false(isp.last_two_blanks('abc\n\n')) | |||
|
736 | ||||
|
737 | nt.assert_true(isp.last_two_blanks('\n\n')) | |||
|
738 | nt.assert_true(isp.last_two_blanks('\n\n ')) | |||
|
739 | nt.assert_true(isp.last_two_blanks('\n \n')) | |||
|
740 | nt.assert_true(isp.last_two_blanks('abc\n\n ')) | |||
|
741 | nt.assert_true(isp.last_two_blanks('abc\n\n\n')) | |||
|
742 | nt.assert_true(isp.last_two_blanks('abc\n\n \n')) | |||
|
743 | nt.assert_true(isp.last_two_blanks('abc\n\n \n ')) | |||
|
744 | nt.assert_true(isp.last_two_blanks('abc\n\n \n \n')) | |||
|
745 | nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n')) | |||
|
746 | nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n')) | |||
|
747 | ||||
|
748 | ||||
|
749 | class CellModeCellMagics(unittest.TestCase): | |||
|
750 | sp = isp.IPythonInputSplitter(input_mode='cell') | |||
|
751 | ||||
|
752 | def test_whole_cell(self): | |||
|
753 | src = "%%cellm line\nbody\n" | |||
|
754 | sp = self.sp | |||
|
755 | sp.push(src) | |||
|
756 | nt.assert_equal(sp.cell_magic_parts, ['body\n']) | |||
|
757 | out = sp.source | |||
|
758 | ref = u"get_ipython()._cell_magic(u'cellm', u'line')\n" | |||
|
759 | nt.assert_equal(out, ref) | |||
|
760 | ||||
|
761 | def test_incremental(self): | |||
|
762 | sp = self.sp | |||
|
763 | src = '%%cellm line2\n' | |||
|
764 | sp.push(src) | |||
|
765 | nt.assert_true(sp.push_accepts_more()) #1 | |||
|
766 | src += '\n' | |||
|
767 | sp.push(src) | |||
|
768 | # Note: if we ever change the logic to allow full blank lines (see | |||
|
769 | # _handle_cell_magic), then the following test should change to true | |||
|
770 | nt.assert_false(sp.push_accepts_more()) #2 | |||
|
771 | # By now, even with full blanks allowed, a second blank should signal | |||
|
772 | # the end. For now this test is only a redundancy safety, but don't | |||
|
773 | # delete it in case we change our mind and the previous one goes to | |||
|
774 | # true. | |||
|
775 | src += '\n' | |||
|
776 | sp.push(src) | |||
|
777 | nt.assert_false(sp.push_accepts_more()) #3 | |||
|
778 | ||||
|
779 | def tearDown(self): | |||
|
780 | self.sp.reset() | |||
|
781 | ||||
|
782 | ||||
|
783 | class LineModeCellMagics(unittest.TestCase): | |||
|
784 | sp = isp.IPythonInputSplitter(input_mode='line') | |||
|
785 | ||||
|
786 | def test_whole_cell(self): | |||
|
787 | src = "%%cellm line\nbody\n" | |||
|
788 | sp = self.sp | |||
|
789 | sp.push(src) | |||
|
790 | nt.assert_equal(sp.cell_magic_parts, ['body\n']) | |||
|
791 | out = sp.source | |||
|
792 | ref = u"get_ipython()._cell_magic(u'cellm', u'line')\n" | |||
|
793 | nt.assert_equal(out, ref) | |||
|
794 | ||||
|
795 | def test_incremental(self): | |||
|
796 | sp = self.sp | |||
|
797 | sp.push('%%cellm line2\n') | |||
|
798 | nt.assert_true(sp.push_accepts_more()) #1 | |||
|
799 | sp.push('\n') | |||
|
800 | nt.assert_false(sp.push_accepts_more()) #2 | |||
|
801 | ||||
|
802 | def tearDown(self): | |||
|
803 | self.sp.reset() |
General Comments 0
You need to be logged in to leave comments.
Login now