Show More
@@ -0,0 +1,26 b'' | |||
|
1 | from IPython.core.splitinput import split_user_input | |
|
2 | from IPython.testing import tools as tt | |
|
3 | ||
|
4 | tests = [ | |
|
5 | ('x=1', ('', '', 'x', '=1')), | |
|
6 | ('?', ('', '?', '', '')), | |
|
7 | ('??', ('', '??', '', '')), | |
|
8 | (' ?', (' ', '?', '', '')), | |
|
9 | (' ??', (' ', '??', '', '')), | |
|
10 | ('??x', ('', '??', 'x', '')), | |
|
11 | ('?x=1', ('', '?', 'x', '=1')), | |
|
12 | ('!ls', ('', '!', 'ls', '')), | |
|
13 | (' !ls', (' ', '!', 'ls', '')), | |
|
14 | ('!!ls', ('', '!!', 'ls', '')), | |
|
15 | (' !!ls', (' ', '!!', 'ls', '')), | |
|
16 | (',ls', ('', ',', 'ls', '')), | |
|
17 | (';ls', ('', ';', 'ls', '')), | |
|
18 | (' ;ls', (' ', ';', 'ls', '')), | |
|
19 | ('f.g(x)', ('', '', 'f.g', '(x)')), | |
|
20 | ('f.g (x)', ('', '', 'f.g', '(x)')), | |
|
21 | ('?%hist', ('', '?', '%hist', '')), | |
|
22 | ('?x*', ('', '?', 'x*', '')), | |
|
23 | ] | |
|
24 | ||
|
25 | def test_split_user_input(): | |
|
26 | return tt.check_pairs(split_user_input, tests) |
@@ -74,6 +74,7 b' import tokenize' | |||
|
74 | 74 | from StringIO import StringIO |
|
75 | 75 | |
|
76 | 76 | # IPython modules |
|
77 | from IPython.core.splitinput import split_user_input, LineInfo | |
|
77 | 78 | from IPython.utils.text import make_quoted_expr |
|
78 | 79 | from IPython.utils.py3compat import cast_unicode |
|
79 | 80 | |
@@ -482,132 +483,10 b' class InputSplitter(object):' | |||
|
482 | 483 | # Functions and classes for IPython-specific syntactic support |
|
483 | 484 | #----------------------------------------------------------------------------- |
|
484 | 485 | |
|
485 | # RegExp for splitting line contents into pre-char//first word-method//rest. | |
|
486 | # For clarity, each group in on one line. | |
|
487 | ||
|
488 | line_split = re.compile(""" | |
|
489 | ^(\s*) # any leading space | |
|
490 | ([,;/%]|!!?|\?\??) # escape character or characters | |
|
491 | \s*(%?[\w\.\*]*) # function/method, possibly with leading % | |
|
492 | # to correctly treat things like '?%magic' | |
|
493 | (\s+.*$|$) # rest of line | |
|
494 | """, re.VERBOSE) | |
|
495 | ||
|
496 | ||
|
497 | def split_user_input(line): | |
|
498 | """Split user input into early whitespace, esc-char, function part and rest. | |
|
499 | ||
|
500 | This is currently handles lines with '=' in them in a very inconsistent | |
|
501 | manner. | |
|
502 | ||
|
503 | Examples | |
|
504 | ======== | |
|
505 | >>> split_user_input('x=1') | |
|
506 | ('', '', 'x=1', '') | |
|
507 | >>> split_user_input('?') | |
|
508 | ('', '?', '', '') | |
|
509 | >>> split_user_input('??') | |
|
510 | ('', '??', '', '') | |
|
511 | >>> split_user_input(' ?') | |
|
512 | (' ', '?', '', '') | |
|
513 | >>> split_user_input(' ??') | |
|
514 | (' ', '??', '', '') | |
|
515 | >>> split_user_input('??x') | |
|
516 | ('', '??', 'x', '') | |
|
517 | >>> split_user_input('?x=1') | |
|
518 | ('', '', '?x=1', '') | |
|
519 | >>> split_user_input('!ls') | |
|
520 | ('', '!', 'ls', '') | |
|
521 | >>> split_user_input(' !ls') | |
|
522 | (' ', '!', 'ls', '') | |
|
523 | >>> split_user_input('!!ls') | |
|
524 | ('', '!!', 'ls', '') | |
|
525 | >>> split_user_input(' !!ls') | |
|
526 | (' ', '!!', 'ls', '') | |
|
527 | >>> split_user_input(',ls') | |
|
528 | ('', ',', 'ls', '') | |
|
529 | >>> split_user_input(';ls') | |
|
530 | ('', ';', 'ls', '') | |
|
531 | >>> split_user_input(' ;ls') | |
|
532 | (' ', ';', 'ls', '') | |
|
533 | >>> split_user_input('f.g(x)') | |
|
534 | ('', '', 'f.g(x)', '') | |
|
535 | >>> split_user_input('f.g (x)') | |
|
536 | ('', '', 'f.g', '(x)') | |
|
537 | >>> split_user_input('?%hist') | |
|
538 | ('', '?', '%hist', '') | |
|
539 | >>> split_user_input('?x*') | |
|
540 | ('', '?', 'x*', '') | |
|
541 | """ | |
|
542 | match = line_split.match(line) | |
|
543 | if match: | |
|
544 | lspace, esc, fpart, rest = match.groups() | |
|
545 | else: | |
|
546 | # print "match failed for line '%s'" % line | |
|
547 | try: | |
|
548 | fpart, rest = line.split(None, 1) | |
|
549 | except ValueError: | |
|
550 | # print "split failed for line '%s'" % line | |
|
551 | fpart, rest = line,'' | |
|
552 | lspace = re.match('^(\s*)(.*)', line).groups()[0] | |
|
553 | esc = '' | |
|
554 | ||
|
555 | # fpart has to be a valid python identifier, so it better be only pure | |
|
556 | # ascii, no unicode: | |
|
557 | try: | |
|
558 | fpart = fpart.encode('ascii') | |
|
559 | except UnicodeEncodeError: | |
|
560 | lspace = unicode(lspace) | |
|
561 | rest = fpart + u' ' + rest | |
|
562 | fpart = u'' | |
|
563 | ||
|
564 | #print 'line:<%s>' % line # dbg | |
|
565 | #print 'esc <%s> fpart <%s> rest <%s>' % (esc,fpart.strip(),rest) # dbg | |
|
566 | return lspace, esc, fpart.strip(), rest.lstrip() | |
|
567 | ||
|
568 | ||
|
569 | 486 | # The escaped translators ALL receive a line where their own escape has been |
|
570 | 487 | # stripped. Only '?' is valid at the end of the line, all others can only be |
|
571 | 488 | # placed at the start. |
|
572 | 489 | |
|
573 | class LineInfo(object): | |
|
574 | """A single line of input and associated info. | |
|
575 | ||
|
576 | This is a utility class that mostly wraps the output of | |
|
577 | :func:`split_user_input` into a convenient object to be passed around | |
|
578 | during input transformations. | |
|
579 | ||
|
580 | Includes the following as properties: | |
|
581 | ||
|
582 | line | |
|
583 | The original, raw line | |
|
584 | ||
|
585 | lspace | |
|
586 | Any early whitespace before actual text starts. | |
|
587 | ||
|
588 | esc | |
|
589 | The initial esc character (or characters, for double-char escapes like | |
|
590 | '??' or '!!'). | |
|
591 | ||
|
592 | fpart | |
|
593 | The 'function part', which is basically the maximal initial sequence | |
|
594 | of valid python identifiers and the '.' character. This is what is | |
|
595 | checked for alias and magic transformations, used for auto-calling, | |
|
596 | etc. | |
|
597 | ||
|
598 | rest | |
|
599 | Everything else on the line. | |
|
600 | """ | |
|
601 | def __init__(self, line): | |
|
602 | self.line = line | |
|
603 | self.lspace, self.esc, self.fpart, self.rest = \ | |
|
604 | split_user_input(line) | |
|
605 | ||
|
606 | def __str__(self): | |
|
607 | return "LineInfo [%s|%s|%s|%s]" % (self.lspace, self.esc, | |
|
608 | self.fpart, self.rest) | |
|
609 | ||
|
610 | ||
|
611 | 490 | # Transformations of the special syntaxes that don't rely on an explicit escape |
|
612 | 491 | # character but instead on patterns on the input line |
|
613 | 492 | |
@@ -690,10 +569,10 b' def _make_help_call(target, esc, lspace, next_input=None):' | |||
|
690 | 569 | |
|
691 | 570 | _initial_space_re = re.compile(r'\s*') |
|
692 | 571 | _help_end_re = re.compile(r"""(%? |
|
693 |
[a-zA-Z_*][ |
|
|
694 |
(\.[a-zA-Z_*][ |
|
|
572 | [a-zA-Z_*][\w*]* # Variable name | |
|
573 | (\.[a-zA-Z_*][\w*]*)* # .etc.etc | |
|
695 | 574 | ) |
|
696 |
(\?\??)$ |
|
|
575 | (\?\??)$ # ? or ??""", | |
|
697 | 576 | re.VERBOSE) |
|
698 | 577 | def transform_help_end(line): |
|
699 | 578 | """Translate lines with ?/?? at the end""" |
@@ -703,7 +582,6 b' def transform_help_end(line):' | |||
|
703 | 582 | target = m.group(1) |
|
704 | 583 | esc = m.group(3) |
|
705 | 584 | lspace = _initial_space_re.match(line).group(0) |
|
706 | newline = _make_help_call(target, esc, lspace) | |
|
707 | 585 | |
|
708 | 586 | # If we're mid-command, put it back on the next prompt for the user. |
|
709 | 587 | next_input = line.rstrip('?') if line.strip() != m.group(0) else None |
@@ -731,14 +609,14 b' class EscapedTransformer(object):' | |||
|
731 | 609 | def _tr_system(line_info): |
|
732 | 610 | "Translate lines escaped with: !" |
|
733 | 611 | cmd = line_info.line.lstrip().lstrip(ESC_SHELL) |
|
734 |
return '%sget_ipython().system(%s)' % (line_info. |
|
|
612 | return '%sget_ipython().system(%s)' % (line_info.pre, | |
|
735 | 613 | make_quoted_expr(cmd)) |
|
736 | 614 | |
|
737 | 615 | @staticmethod |
|
738 | 616 | def _tr_system2(line_info): |
|
739 | 617 | "Translate lines escaped with: !!" |
|
740 | 618 | cmd = line_info.line.lstrip()[2:] |
|
741 |
return '%sget_ipython().getoutput(%s)' % (line_info. |
|
|
619 | return '%sget_ipython().getoutput(%s)' % (line_info.pre, | |
|
742 | 620 | make_quoted_expr(cmd)) |
|
743 | 621 | |
|
744 | 622 | @staticmethod |
@@ -748,33 +626,33 b' class EscapedTransformer(object):' | |||
|
748 | 626 | if not line_info.line[1:]: |
|
749 | 627 | return 'get_ipython().show_usage()' |
|
750 | 628 | |
|
751 |
return _make_help_call(line_info. |
|
|
629 | return _make_help_call(line_info.ifun, line_info.esc, line_info.pre) | |
|
752 | 630 | |
|
753 | 631 | @staticmethod |
|
754 | 632 | def _tr_magic(line_info): |
|
755 | 633 | "Translate lines escaped with: %" |
|
756 | 634 | tpl = '%sget_ipython().magic(%s)' |
|
757 |
cmd = make_quoted_expr(' '.join([line_info. |
|
|
758 |
|
|
|
759 |
return tpl % (line_info. |
|
|
635 | cmd = make_quoted_expr(' '.join([line_info.ifun, | |
|
636 | line_info.the_rest]).strip()) | |
|
637 | return tpl % (line_info.pre, cmd) | |
|
760 | 638 | |
|
761 | 639 | @staticmethod |
|
762 | 640 | def _tr_quote(line_info): |
|
763 | 641 | "Translate lines escaped with: ," |
|
764 |
return '%s%s("%s")' % (line_info. |
|
|
765 | '", "'.join(line_info.rest.split()) ) | |
|
642 | return '%s%s("%s")' % (line_info.pre, line_info.ifun, | |
|
643 | '", "'.join(line_info.the_rest.split()) ) | |
|
766 | 644 | |
|
767 | 645 | @staticmethod |
|
768 | 646 | def _tr_quote2(line_info): |
|
769 | 647 | "Translate lines escaped with: ;" |
|
770 |
return '%s%s("%s")' % (line_info. |
|
|
771 | line_info.rest) | |
|
648 | return '%s%s("%s")' % (line_info.pre, line_info.ifun, | |
|
649 | line_info.the_rest) | |
|
772 | 650 | |
|
773 | 651 | @staticmethod |
|
774 | 652 | def _tr_paren(line_info): |
|
775 | 653 | "Translate lines escaped with: /" |
|
776 |
return '%s%s(%s)' % (line_info. |
|
|
777 | ", ".join(line_info.rest.split())) | |
|
654 | return '%s%s(%s)' % (line_info.pre, line_info.ifun, | |
|
655 | ", ".join(line_info.the_rest.split())) | |
|
778 | 656 | |
|
779 | 657 | def __call__(self, line): |
|
780 | 658 | """Class to transform lines that are explicitly escaped out. |
@@ -843,7 +721,7 b' class IPythonInputSplitter(InputSplitter):' | |||
|
843 | 721 | lines_list = lines.splitlines() |
|
844 | 722 | |
|
845 | 723 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
|
846 |
transform_escaped, |
|
|
724 | transform_help_end, transform_escaped, | |
|
847 | 725 | transform_assign_system, transform_assign_magic] |
|
848 | 726 | |
|
849 | 727 | # Transform logic |
@@ -32,7 +32,7 b' from IPython.core.alias import AliasManager' | |||
|
32 | 32 | from IPython.core.autocall import IPyAutocall |
|
33 | 33 | from IPython.config.configurable import Configurable |
|
34 | 34 | from IPython.core.macro import Macro |
|
35 | from IPython.core.splitinput import split_user_input | |
|
35 | from IPython.core.splitinput import split_user_input, LineInfo | |
|
36 | 36 | from IPython.core import page |
|
37 | 37 | |
|
38 | 38 | from IPython.utils.traitlets import List, Int, Any, Unicode, CBool, Bool, Instance |
@@ -92,78 +92,6 b' def is_shadowed(identifier, ip):' | |||
|
92 | 92 | |
|
93 | 93 | |
|
94 | 94 | #----------------------------------------------------------------------------- |
|
95 | # The LineInfo class used throughout | |
|
96 | #----------------------------------------------------------------------------- | |
|
97 | ||
|
98 | ||
|
99 | class LineInfo(object): | |
|
100 | """A single line of input and associated info. | |
|
101 | ||
|
102 | Includes the following as properties: | |
|
103 | ||
|
104 | line | |
|
105 | The original, raw line | |
|
106 | ||
|
107 | continue_prompt | |
|
108 | Is this line a continuation in a sequence of multiline input? | |
|
109 | ||
|
110 | pre | |
|
111 | The initial esc character or whitespace. | |
|
112 | ||
|
113 | pre_char | |
|
114 | The escape character(s) in pre or the empty string if there isn't one. | |
|
115 | Note that '!!' is a possible value for pre_char. Otherwise it will | |
|
116 | always be a single character. | |
|
117 | ||
|
118 | pre_whitespace | |
|
119 | The leading whitespace from pre if it exists. If there is a pre_char, | |
|
120 | this is just ''. | |
|
121 | ||
|
122 | ifun | |
|
123 | The 'function part', which is basically the maximal initial sequence | |
|
124 | of valid python identifiers and the '.' character. This is what is | |
|
125 | checked for alias and magic transformations, used for auto-calling, | |
|
126 | etc. | |
|
127 | ||
|
128 | the_rest | |
|
129 | Everything else on the line. | |
|
130 | """ | |
|
131 | def __init__(self, line, continue_prompt): | |
|
132 | self.line = line | |
|
133 | self.continue_prompt = continue_prompt | |
|
134 | self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line) | |
|
135 | ||
|
136 | self.pre_char = self.pre.strip() | |
|
137 | if self.pre_char: | |
|
138 | self.pre_whitespace = '' # No whitespace allowd before esc chars | |
|
139 | else: | |
|
140 | self.pre_whitespace = self.pre | |
|
141 | ||
|
142 | self._oinfo = None | |
|
143 | ||
|
144 | def ofind(self, ip): | |
|
145 | """Do a full, attribute-walking lookup of the ifun in the various | |
|
146 | namespaces for the given IPython InteractiveShell instance. | |
|
147 | ||
|
148 | Return a dict with keys: found,obj,ospace,ismagic | |
|
149 | ||
|
150 | Note: can cause state changes because of calling getattr, but should | |
|
151 | only be run if autocall is on and if the line hasn't matched any | |
|
152 | other, less dangerous handlers. | |
|
153 | ||
|
154 | Does cache the results of the call, so can be called multiple times | |
|
155 | without worrying about *further* damaging state. | |
|
156 | """ | |
|
157 | if not self._oinfo: | |
|
158 | # ip.shell._ofind is actually on the Magic class! | |
|
159 | self._oinfo = ip.shell._ofind(self.ifun) | |
|
160 | return self._oinfo | |
|
161 | ||
|
162 | def __str__(self): | |
|
163 | return "Lineinfo [%s|%s|%s]" %(self.pre, self.ifun, self.the_rest) | |
|
164 | ||
|
165 | ||
|
166 | #----------------------------------------------------------------------------- | |
|
167 | 95 | # Main Prefilter manager |
|
168 | 96 | #----------------------------------------------------------------------------- |
|
169 | 97 |
@@ -1,6 +1,7 b'' | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | 2 | """ |
|
3 | Simple utility for splitting user input. | |
|
3 | Simple utility for splitting user input. This is used by both inputsplitter and | |
|
4 | prefilter. | |
|
4 | 5 | |
|
5 | 6 | Authors: |
|
6 | 7 | |
@@ -28,36 +29,28 b' from IPython.utils import py3compat' | |||
|
28 | 29 | # Main function |
|
29 | 30 | #----------------------------------------------------------------------------- |
|
30 | 31 | |
|
31 | ||
|
32 | 32 | # RegExp for splitting line contents into pre-char//first word-method//rest. |
|
33 | 33 | # For clarity, each group in on one line. |
|
34 | 34 | |
|
35 |
# WARNING: update the regexp if the escapes in interactiveshell are changed, as |
|
|
36 | # are hardwired in. | |
|
35 | # WARNING: update the regexp if the escapes in interactiveshell are changed, as | |
|
36 | # they are hardwired in. | |
|
37 | 37 | |
|
38 | 38 | # Although it's not solely driven by the regex, note that: |
|
39 | 39 | # ,;/% only trigger if they are the first character on the line |
|
40 | 40 | # ! and !! trigger if they are first char(s) *or* follow an indent |
|
41 | 41 | # ? triggers as first or last char. |
|
42 | 42 | |
|
43 | # The four parts of the regex are: | |
|
44 | # 1) pre: initial whitespace | |
|
45 | # 2) esc: escape character | |
|
46 | # 3) ifun: first word/method (mix of \w and '.') | |
|
47 | # 4) the_rest: rest of line (separated from ifun by space if non-empty) | |
|
48 | line_split = re.compile(r'^(\s*)' | |
|
49 | r'([,;/%?]|!!?)?' | |
|
50 | r'\s*([\w\.]+)' | |
|
51 | r'(.*$|$)') | |
|
52 | ||
|
53 | # r'[\w\.]+' | |
|
54 | # r'\s*=\s*%.*' | |
|
43 | line_split = re.compile(""" | |
|
44 | ^(\s*) # any leading space | |
|
45 | ([,;/%]|!!?|\?\??)? # escape character or characters | |
|
46 | \s*(%?[\w\.\*]*) # function/method, possibly with leading % | |
|
47 | # to correctly treat things like '?%magic' | |
|
48 | (.*?$|$) # rest of line | |
|
49 | """, re.VERBOSE) | |
|
55 | 50 | |
|
56 | 51 | def split_user_input(line, pattern=None): |
|
57 |
"""Split user input into |
|
|
58 | ||
|
59 | This is currently handles lines with '=' in them in a very inconsistent | |
|
60 | manner. | |
|
52 | """Split user input into initial whitespace, escape character, function part | |
|
53 | and the rest. | |
|
61 | 54 | """ |
|
62 | 55 | # We need to ensure that the rest of this routine deals only with unicode |
|
63 | 56 | line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8') |
@@ -76,11 +69,70 b' def split_user_input(line, pattern=None):' | |||
|
76 | 69 | esc = "" |
|
77 | 70 | else: |
|
78 | 71 | pre, esc, ifun, the_rest = match.groups() |
|
79 | ||
|
80 | if not py3compat.isidentifier(ifun, dotted=True): | |
|
81 | the_rest = ifun + u' ' + the_rest | |
|
82 | ifun = u'' | |
|
83 | 72 | |
|
84 | 73 | #print 'line:<%s>' % line # dbg |
|
85 | 74 | #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg |
|
86 | return pre, esc, ifun.strip(), the_rest.lstrip() | |
|
75 | return pre, esc or '', ifun.strip(), the_rest.lstrip() | |
|
76 | ||
|
77 | class LineInfo(object): | |
|
78 | """A single line of input and associated info. | |
|
79 | ||
|
80 | Includes the following as properties: | |
|
81 | ||
|
82 | line | |
|
83 | The original, raw line | |
|
84 | ||
|
85 | continue_prompt | |
|
86 | Is this line a continuation in a sequence of multiline input? | |
|
87 | ||
|
88 | pre | |
|
89 | Any leading whitespace. | |
|
90 | ||
|
91 | esc | |
|
92 | The escape character(s) in pre or the empty string if there isn't one. | |
|
93 | Note that '!!' and '??' are possible values for esc. Otherwise it will | |
|
94 | always be a single character. | |
|
95 | ||
|
96 | ifun | |
|
97 | The 'function part', which is basically the maximal initial sequence | |
|
98 | of valid python identifiers and the '.' character. This is what is | |
|
99 | checked for alias and magic transformations, used for auto-calling, | |
|
100 | etc. In contrast to Python identifiers, it may start with "%" and contain | |
|
101 | "*". | |
|
102 | ||
|
103 | the_rest | |
|
104 | Everything else on the line. | |
|
105 | """ | |
|
106 | def __init__(self, line, continue_prompt=False): | |
|
107 | self.line = line | |
|
108 | self.continue_prompt = continue_prompt | |
|
109 | self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line) | |
|
110 | ||
|
111 | self.pre_char = self.pre.strip() | |
|
112 | if self.pre_char: | |
|
113 | self.pre_whitespace = '' # No whitespace allowd before esc chars | |
|
114 | else: | |
|
115 | self.pre_whitespace = self.pre | |
|
116 | ||
|
117 | self._oinfo = None | |
|
118 | ||
|
119 | def ofind(self, ip): | |
|
120 | """Do a full, attribute-walking lookup of the ifun in the various | |
|
121 | namespaces for the given IPython InteractiveShell instance. | |
|
122 | ||
|
123 | Return a dict with keys: found,obj,ospace,ismagic | |
|
124 | ||
|
125 | Note: can cause state changes because of calling getattr, but should | |
|
126 | only be run if autocall is on and if the line hasn't matched any | |
|
127 | other, less dangerous handlers. | |
|
128 | ||
|
129 | Does cache the results of the call, so can be called multiple times | |
|
130 | without worrying about *further* damaging state. | |
|
131 | """ | |
|
132 | if not self._oinfo: | |
|
133 | # ip.shell._ofind is actually on the Magic class! | |
|
134 | self._oinfo = ip.shell._ofind(self.ifun) | |
|
135 | return self._oinfo | |
|
136 | ||
|
137 | def __str__(self): | |
|
138 | return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest) |
@@ -394,9 +394,8 b' def test_LineInfo():' | |||
|
394 | 394 | def test_split_user_input(): |
|
395 | 395 | """Unicode test - split_user_input already has good doctests""" |
|
396 | 396 | line = u"Pérez Fernando" |
|
397 | parts = isp.split_user_input(line) | |
|
398 | 397 | parts_expected = (u'', u'', u'', line) |
|
399 | nt.assert_equal(parts, parts_expected) | |
|
398 | tt.check_pairs(isp.split_user_input, [(line, parts_expected),]) | |
|
400 | 399 | |
|
401 | 400 | |
|
402 | 401 | # Transformer tests |
@@ -611,7 +610,8 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
611 | 610 | |
|
612 | 611 | isp.push(raw) |
|
613 | 612 | out, out_raw = isp.source_raw_reset() |
|
614 |
self.assertEqual(out.rstrip(), out_t |
|
|
613 | self.assertEqual(out.rstrip(), out_t, | |
|
614 | tt.pair_fail_msg.format("inputsplitter",raw, out_t, out)) | |
|
615 | 615 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) |
|
616 | 616 | |
|
617 | 617 | def test_syntax_multiline(self): |
@@ -295,7 +295,7 b' class TempFileMixin(object):' | |||
|
295 | 295 | # delete it. I have no clue why |
|
296 | 296 | pass |
|
297 | 297 | |
|
298 |
pair_fail_msg = ("Testing |
|
|
298 | pair_fail_msg = ("Testing {0}\n\n" | |
|
299 | 299 | "In:\n" |
|
300 | 300 | " {1!r}\n" |
|
301 | 301 | "Expected:\n" |
@@ -318,9 +318,10 b' def check_pairs(func, pairs):' | |||
|
318 | 318 | None. Raises an AssertionError if any output does not match the expected |
|
319 | 319 | value. |
|
320 | 320 | """ |
|
321 | name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>")) | |
|
321 | 322 | for inp, expected in pairs: |
|
322 | 323 | out = func(inp) |
|
323 |
assert out == expected, pair_fail_msg.format( |
|
|
324 | assert out == expected, pair_fail_msg.format(name, inp, expected, out) | |
|
324 | 325 | |
|
325 | 326 | @contextmanager |
|
326 | 327 | def mute_warn(): |
@@ -342,4 +343,3 b' def make_tempfile(name):' | |||
|
342 | 343 | yield |
|
343 | 344 | finally: |
|
344 | 345 | os.unlink(name) |
|
345 |
General Comments 0
You need to be logged in to leave comments.
Login now