Show More
@@ -10,9 +10,30 b' with full support for the extended IPython syntax (magics, system calls, etc).' | |||
|
10 | 10 | |
|
11 | 11 | For more details, see the class docstring below. |
|
12 | 12 | |
|
13 | Syntax Transformations | |
|
14 | ---------------------- | |
|
15 | ||
|
16 | One of the main jobs of the code in this file is to apply all syntax | |
|
17 | transformations that make up 'the IPython language', i.e. magics, shell | |
|
18 | escapes, etc. All transformations should be implemented as *fully stateless* | |
|
19 | entities, that simply take one line as their input and return a line. | |
|
20 | Internally for implementation purposes they may be a normal function or a | |
|
21 | callable object, but the only input they receive will be a single line and they | |
|
22 | should only return a line, without holding any data-dependent state between | |
|
23 | calls. | |
|
24 | ||
|
25 | As an example, the EscapedTransformer is a class so we can more clearly group | |
|
26 | together the functionality of dispatching to individual functions based on the | |
|
27 | starting escape character, but the only method for public use is its call | |
|
28 | method. | |
|
29 | ||
|
30 | ||
|
13 | 31 | ToDo |
|
14 | 32 | ---- |
|
15 | 33 | |
|
34 | - Should we make push() actually raise an exception once push_accepts_more() | |
|
35 | returns False? | |
|
36 | ||
|
16 | 37 | - Naming cleanups. The tr_* names aren't the most elegant, though now they are |
|
17 | 38 | at least just attributes of a class so not really very exposed. |
|
18 | 39 | |
@@ -670,34 +691,34 b' class EscapedTransformer(object):' | |||
|
670 | 691 | """Class to transform lines that are explicitly escaped out.""" |
|
671 | 692 | |
|
672 | 693 | def __init__(self): |
|
673 | tr = { ESC_SHELL : self.tr_system, | |
|
674 | ESC_SH_CAP : self.tr_system2, | |
|
675 | ESC_HELP : self.tr_help, | |
|
676 | ESC_HELP2 : self.tr_help, | |
|
677 | ESC_MAGIC : self.tr_magic, | |
|
678 | ESC_QUOTE : self.tr_quote, | |
|
679 | ESC_QUOTE2 : self.tr_quote2, | |
|
680 | ESC_PAREN : self.tr_paren } | |
|
694 | tr = { ESC_SHELL : self._tr_system, | |
|
695 | ESC_SH_CAP : self._tr_system2, | |
|
696 | ESC_HELP : self._tr_help, | |
|
697 | ESC_HELP2 : self._tr_help, | |
|
698 | ESC_MAGIC : self._tr_magic, | |
|
699 | ESC_QUOTE : self._tr_quote, | |
|
700 | ESC_QUOTE2 : self._tr_quote2, | |
|
701 | ESC_PAREN : self._tr_paren } | |
|
681 | 702 | self.tr = tr |
|
682 | 703 | |
|
683 | 704 | # Support for syntax transformations that use explicit escapes typed by the |
|
684 | 705 | # user at the beginning of a line |
|
685 | 706 | @staticmethod |
|
686 | def tr_system(line_info): | |
|
707 | def _tr_system(line_info): | |
|
687 | 708 | "Translate lines escaped with: !" |
|
688 | 709 | cmd = line_info.line.lstrip().lstrip(ESC_SHELL) |
|
689 | 710 | return '%sget_ipython().system(%s)' % (line_info.lspace, |
|
690 | 711 | make_quoted_expr(cmd)) |
|
691 | 712 | |
|
692 | 713 | @staticmethod |
|
693 | def tr_system2(line_info): | |
|
714 | def _tr_system2(line_info): | |
|
694 | 715 | "Translate lines escaped with: !!" |
|
695 | 716 | cmd = line_info.line.lstrip()[2:] |
|
696 | 717 | return '%sget_ipython().getoutput(%s)' % (line_info.lspace, |
|
697 | 718 | make_quoted_expr(cmd)) |
|
698 | 719 | |
|
699 | 720 | @staticmethod |
|
700 | def tr_help(line_info): | |
|
721 | def _tr_help(line_info): | |
|
701 | 722 | "Translate lines escaped with: ?/??" |
|
702 | 723 | # A naked help line should just fire the intro help screen |
|
703 | 724 | if not line_info.line[1:]: |
@@ -723,7 +744,7 b' class EscapedTransformer(object):' | |||
|
723 | 744 | ' '.join([line_info.fpart, line_info.rest]).strip()) |
|
724 | 745 | |
|
725 | 746 | @staticmethod |
|
726 | def tr_magic(line_info): | |
|
747 | def _tr_magic(line_info): | |
|
727 | 748 | "Translate lines escaped with: %" |
|
728 | 749 | tpl = '%sget_ipython().magic(%s)' |
|
729 | 750 | cmd = make_quoted_expr(' '.join([line_info.fpart, |
@@ -731,19 +752,19 b' class EscapedTransformer(object):' | |||
|
731 | 752 | return tpl % (line_info.lspace, cmd) |
|
732 | 753 | |
|
733 | 754 | @staticmethod |
|
734 | def tr_quote(line_info): | |
|
755 | def _tr_quote(line_info): | |
|
735 | 756 | "Translate lines escaped with: ," |
|
736 | 757 | return '%s%s("%s")' % (line_info.lspace, line_info.fpart, |
|
737 | 758 | '", "'.join(line_info.rest.split()) ) |
|
738 | 759 | |
|
739 | 760 | @staticmethod |
|
740 | def tr_quote2(line_info): | |
|
761 | def _tr_quote2(line_info): | |
|
741 | 762 | "Translate lines escaped with: ;" |
|
742 | 763 | return '%s%s("%s")' % (line_info.lspace, line_info.fpart, |
|
743 | 764 | line_info.rest) |
|
744 | 765 | |
|
745 | 766 | @staticmethod |
|
746 | def tr_paren(line_info): | |
|
767 | def _tr_paren(line_info): | |
|
747 | 768 | "Translate lines escaped with: /" |
|
748 | 769 | return '%s%s(%s)' % (line_info.lspace, line_info.fpart, |
|
749 | 770 | ", ".join(line_info.rest.split())) |
@@ -751,7 +772,7 b' class EscapedTransformer(object):' | |||
|
751 | 772 | def __call__(self, line): |
|
752 | 773 | """Class to transform lines that are explicitly escaped out. |
|
753 | 774 | |
|
754 | This calls the above tr_* static methods for the actual line | |
|
775 | This calls the above _tr_* static methods for the actual line | |
|
755 | 776 | translations.""" |
|
756 | 777 | |
|
757 | 778 | # Empty lines just get returned unmodified |
@@ -765,13 +786,14 b' class EscapedTransformer(object):' | |||
|
765 | 786 | # All other escapes are only valid at the start |
|
766 | 787 | if not line_info.esc in self.tr: |
|
767 | 788 | if line.endswith(ESC_HELP): |
|
768 | return self.tr_help(line_info) | |
|
789 | return self._tr_help(line_info) | |
|
769 | 790 | else: |
|
770 | 791 | # If we don't recognize the escape, don't modify the line |
|
771 | 792 | return line |
|
772 | 793 | |
|
773 | 794 | return self.tr[line_info.esc](line_info) |
|
774 | 795 | |
|
796 | ||
|
775 | 797 | # A function-looking object to be used by the rest of the code. The purpose of |
|
776 | 798 | # the class in this case is to organize related functionality, more than to |
|
777 | 799 | # manage state. |
@@ -583,7 +583,7 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
583 | 583 | out_t = '\n'.join(out_t_parts).rstrip() |
|
584 | 584 | self.assertEqual(out, out_t) |
|
585 | 585 | |
|
586 | ||
|
586 | ||
|
587 | 587 | #----------------------------------------------------------------------------- |
|
588 | 588 | # Main - use as a script |
|
589 | 589 | #----------------------------------------------------------------------------- |
@@ -615,6 +615,7 b" if __name__ == '__main__':" | |||
|
615 | 615 | |
|
616 | 616 | # Here we just return input so we can use it in a test suite, but a |
|
617 | 617 | # real interpreter would instead send it for execution somewhere. |
|
618 | #src = isp.source; raise EOFError # dbg | |
|
618 | 619 | src = isp.source_reset() |
|
619 | 620 | print 'Input source was:\n', src |
|
620 | 621 | except EOFError: |
General Comments 0
You need to be logged in to leave comments.
Login now