##// END OF EJS Templates
First implementation of cell magics that goes via inputsplitter....
Fernando Perez -
Show More
@@ -55,7 +55,7 b' Authors'
55 55 * Brian Granger
56 56 """
57 57 #-----------------------------------------------------------------------------
58 # Copyright (C) 2010-2011 The IPython Development Team
58 # Copyright (C) 2010 The IPython Development Team
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
@@ -685,20 +685,23 b' class IPythonInputSplitter(InputSplitter):'
685 685 # String with raw, untransformed input.
686 686 source_raw = ''
687 687
688 cell_magic_body = None
689
688 690 # Private attributes
689 691
690 692 # List with lines of raw input accumulated so far.
691 693 _buffer_raw = None
692 694
693 695 def __init__(self, input_mode=None):
694 InputSplitter.__init__(self, input_mode)
696 super(IPythonInputSplitter, self).__init__(input_mode)
695 697 self._buffer_raw = []
696 698
697 699 def reset(self):
698 700 """Reset the input buffer and associated state."""
699 InputSplitter.reset(self)
701 super(IPythonInputSplitter, self).reset()
700 702 self._buffer_raw[:] = []
701 703 self.source_raw = ''
704 self.cell_magic_body = None
702 705
703 706 def source_raw_reset(self):
704 707 """Return input and raw source and perform a full reset.
@@ -710,6 +713,26 b' class IPythonInputSplitter(InputSplitter):'
710 713
711 714 def push(self, lines):
712 715 """Push one or more lines of IPython input.
716
717 This stores the given lines and returns a status code indicating
718 whether the code forms a complete Python block or not, after processing
719 all input lines for special IPython syntax.
720
721 Any exceptions generated in compilation are swallowed, but if an
722 exception was produced, the method returns True.
723
724 Parameters
725 ----------
726 lines : string
727 One or more lines of Python input.
728
729 Returns
730 -------
731 is_complete : boolean
732 True if the current input source (the result of the current input
733 plus prior inputs) forms a complete Python execution block. Note that
734 this value is also stored as a private attribute (_is_complete), so it
735 can be queried at any time.
713 736 """
714 737 if not lines:
715 738 return super(IPythonInputSplitter, self).push(lines)
@@ -717,6 +740,20 b' class IPythonInputSplitter(InputSplitter):'
717 740 # We must ensure all input is pure unicode
718 741 lines = cast_unicode(lines, self.encoding)
719 742
743 # cell magic support
744 #print('IM:', self.input_mode,'\n'+lines); print('---') # dbg
745 #if self.input_mode == 'cell' and lines.startswith('%%'):
746 if lines.startswith('%%'):
747 # Cell magics bypass all further transformations
748 self.reset()
749 self._is_complete = is_complete = True
750 first, _, body = lines.partition('\n')
751 magic_name, _, line = first.partition(' ')
752 magic_name = magic_name.lstrip(ESC_MAGIC)
753 self.cell_magic_body = body
754 tpl = 'get_ipython()._cell_magic(%r, %r)'
755 lines = tpl % (magic_name, line)
756
720 757 lines_list = lines.splitlines()
721 758
722 759 transforms = [transform_ipy_prompt, transform_classic_prompt,
@@ -2027,7 +2027,7 b' class InteractiveShell(SingletonConfigurable):'
2027 2027 """
2028 2028 fn = self.find_line_magic(magic_name)
2029 2029 if fn is None:
2030 error("Magic function `%s` not found." % magic_name)
2030 error("Line magic function `%%%s` not found." % magic_name)
2031 2031 else:
2032 2032 # Note: this is the distance in the stack to the user's frame.
2033 2033 # This will need to be updated if the internal calling logic gets
@@ -2048,7 +2048,7 b' class InteractiveShell(SingletonConfigurable):'
2048 2048 """
2049 2049 fn = self.find_cell_magic(magic_name)
2050 2050 if fn is None:
2051 error("Magic function `%s` not found." % magic_name)
2051 error("Cell magic function `%%%%%s` not found." % magic_name)
2052 2052 else:
2053 2053 # Note: this is the distance in the stack to the user's frame.
2054 2054 # This will need to be updated if the internal calling logic gets
@@ -2475,6 +2475,11 b' class InteractiveShell(SingletonConfigurable):'
2475 2475 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2476 2476 return self.cell_magic(magic_name, line, cell)
2477 2477
2478 def _cell_magic(self, magic_name, line):
2479 cell = self._current_cell_magic_body
2480 self._current_cell_magic_body = None
2481 return self.cell_magic(magic_name, line, cell)
2482
2478 2483 def run_cell(self, raw_cell, store_history=False, silent=False):
2479 2484 """Run a complete IPython cell.
2480 2485
@@ -2496,11 +2501,14 b' class InteractiveShell(SingletonConfigurable):'
2496 2501 if silent:
2497 2502 store_history = False
2498 2503
2499 if raw_cell.startswith('%%'):
2500 return self.call_cell_magic(raw_cell, store_history)
2504 self.input_splitter.push(raw_cell)
2501 2505
2502 for line in raw_cell.splitlines():
2503 self.input_splitter.push(line)
2506 # Check for cell magics, which leave state behind. This interface is
2507 # ugly, we need to do something cleaner later... Now the logic is
2508 # simply that the input_splitter remembers if there was a cell magic,
2509 # and in that case we grab the cell body.
2510 if self.input_splitter.cell_magic_body is not None:
2511 self._current_cell_magic_body = self.input_splitter.cell_magic_body
2504 2512 cell = self.input_splitter.source_reset()
2505 2513
2506 2514 with self.builtin_trap:
@@ -495,10 +495,12 b' def test_env():'
495 495 class CellMagicTestCase(TestCase):
496 496
497 497 def check_ident(self, magic):
498 # Manually called, we get the result
498 499 out = _ip.cell_magic(magic, 'a', 'b')
499 500 nt.assert_equals(out, ('a','b'))
500 out = _ip.run_cell('%%' + magic +' a\nb')
501 nt.assert_equals(out, ('a','b'))
501 # Via run_cell, it goes into the user's namespace via displayhook
502 _ip.run_cell('%%' + magic +' c\nd')
503 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
502 504
503 505 def test_cell_magic_func_deco(self):
504 506 "Cell magic using simple decorator"
@@ -525,12 +527,19 b' class CellMagicTestCase(TestCase):'
525 527 def cellm3(self, line, cell):
526 528 return line, cell
527 529
530 _ip.register_magics(MyMagics)
531 self.check_ident('cellm3')
532
533 def test_cell_magic_class2(self):
534 "Cell magics declared via a class, #2"
535 @magics_class
536 class MyMagics2(Magics):
537
528 538 @cell_magic('cellm4')
529 539 def cellm33(self, line, cell):
530 540 return line, cell
531
532 _ip.register_magics(MyMagics)
533 self.check_ident('cellm3')
541
542 _ip.register_magics(MyMagics2)
534 543 self.check_ident('cellm4')
535 544 # Check that nothing is registered as 'cellm33'
536 545 c33 = _ip.find_cell_magic('cellm33')
General Comments 0
You need to be logged in to leave comments. Login now