Show More
@@ -70,6 +70,8 b' import ast' | |||
|
70 | 70 | import codeop |
|
71 | 71 | import re |
|
72 | 72 | import sys |
|
73 | import tokenize | |
|
74 | from StringIO import StringIO | |
|
73 | 75 | |
|
74 | 76 | # IPython modules |
|
75 | 77 | from IPython.utils.text import make_quoted_expr |
@@ -155,6 +157,24 b' def remove_comments(src):' | |||
|
155 | 157 | """ |
|
156 | 158 | |
|
157 | 159 | return re.sub('#.*', '', src) |
|
160 | ||
|
161 | def has_comment(src): | |
|
162 | """Indicate whether an input line has (i.e. ends in, or is) a comment. | |
|
163 | ||
|
164 | This uses tokenize, so it can distinguish comments from # inside strings. | |
|
165 | ||
|
166 | Parameters | |
|
167 | ---------- | |
|
168 | src : string | |
|
169 | A single line input string. | |
|
170 | ||
|
171 | Returns | |
|
172 | ------- | |
|
173 | Boolean: True if source has a comment. | |
|
174 | """ | |
|
175 | readline = StringIO(src).readline | |
|
176 | toktypes = set(t[0] for t in tokenize.generate_tokens(readline)) | |
|
177 | return(tokenize.COMMENT in toktypes) | |
|
158 | 178 | |
|
159 | 179 | |
|
160 | 180 | def get_input_encoding(): |
@@ -672,12 +692,19 b' _help_end_re = re.compile(r"""(%?' | |||
|
672 | 692 | def transform_help_end(line): |
|
673 | 693 | """Translate lines with ?/?? at the end""" |
|
674 | 694 | m = _help_end_re.search(line) |
|
675 | if m is None: | |
|
695 | if m is None or has_comment(line): | |
|
676 | 696 | return line |
|
677 | 697 | target = m.group(1) |
|
678 | 698 | esc = m.group(3) |
|
679 | 699 | lspace = _initial_space_re.match(line).group(0) |
|
680 |
|
|
|
700 | newline = _make_help_call(target, esc, lspace) | |
|
701 | ||
|
702 | # If we're mid-command, put it back on the next prompt for the user. | |
|
703 | if line.strip() != m.group(0): | |
|
704 | newline += "; get_ipython().set_next_input(%s)" % \ | |
|
705 | make_quoted_expr(line.rstrip('?')) | |
|
706 | ||
|
707 | return newline | |
|
681 | 708 | |
|
682 | 709 | |
|
683 | 710 | class EscapedTransformer(object): |
@@ -25,6 +25,7 b' import nose.tools as nt' | |||
|
25 | 25 | |
|
26 | 26 | # Our own |
|
27 | 27 | from IPython.core import inputsplitter as isp |
|
28 | from IPython.testing import tools as tt | |
|
28 | 29 | |
|
29 | 30 | #----------------------------------------------------------------------------- |
|
30 | 31 | # Semi-complete examples (also used as tests) |
@@ -92,9 +93,7 b' def test_spaces():' | |||
|
92 | 93 | ('\tx', 1), |
|
93 | 94 | ('\t x', 2), |
|
94 | 95 | ] |
|
95 | ||
|
96 | for s, nsp in tests: | |
|
97 | nt.assert_equal(isp.num_ini_spaces(s), nsp) | |
|
96 | tt.check_pairs(isp.num_ini_spaces, tests) | |
|
98 | 97 | |
|
99 | 98 | |
|
100 | 99 | def test_remove_comments(): |
@@ -106,9 +105,19 b' def test_remove_comments():' | |||
|
106 | 105 | ('line # c \nline#c2 \nline\nline #c\n\n', |
|
107 | 106 | 'line \nline\nline\nline \n\n'), |
|
108 | 107 | ] |
|
109 | ||
|
110 | for inp, out in tests: | |
|
111 | nt.assert_equal(isp.remove_comments(inp), out) | |
|
108 | tt.check_pairs(isp.remove_comments, tests) | |
|
109 | ||
|
110 | def test_has_comment(): | |
|
111 | tests = [('text', False), | |
|
112 | ('text #comment', True), | |
|
113 | ('text #comment\n', True), | |
|
114 | ('#comment', True), | |
|
115 | ('#comment\n', True), | |
|
116 | ('a = "#string"', False), | |
|
117 | ('a = "#string" # comment', True), | |
|
118 | ('a #comment not "string"', True), | |
|
119 | ] | |
|
120 | tt.check_pairs(isp.has_comment, tests) | |
|
112 | 121 | |
|
113 | 122 | |
|
114 | 123 | def test_get_input_encoding(): |
@@ -445,9 +454,10 b' syntax = \\' | |||
|
445 | 454 | ('%hist?', 'get_ipython().magic(u"pinfo %hist")'), |
|
446 | 455 | ('f*?', 'get_ipython().magic(u"psearch f*")'), |
|
447 | 456 | ('ax.*aspe*?', 'get_ipython().magic(u"psearch ax.*aspe*")'), |
|
448 | ('a = abc?', 'get_ipython().magic(u"pinfo abc")'), | |
|
449 | ('a = abc.qe??', 'get_ipython().magic(u"pinfo2 abc.qe")'), | |
|
450 | ('a = *.items?', 'get_ipython().magic(u"psearch *.items")'), | |
|
457 | ('a = abc?', 'get_ipython().magic(u"pinfo abc"); get_ipython().set_next_input(u"a = abc")'), | |
|
458 | ('a = abc.qe??', 'get_ipython().magic(u"pinfo2 abc.qe"); get_ipython().set_next_input(u"a = abc.qe")'), | |
|
459 | ('a = *.items?', 'get_ipython().magic(u"psearch *.items"); get_ipython().set_next_input(u"a = *.items")'), | |
|
460 | ('a*2 #comment?', 'a*2 #comment?'), | |
|
451 | 461 | ], |
|
452 | 462 | |
|
453 | 463 | # Explicit magic calls |
@@ -513,11 +523,11 b' syntax_ml = \\' | |||
|
513 | 523 | |
|
514 | 524 | |
|
515 | 525 | def test_assign_system(): |
|
516 | transform_checker(syntax['assign_system'], isp.transform_assign_system) | |
|
526 | tt.check_pairs(isp.transform_assign_system, syntax['assign_system']) | |
|
517 | 527 | |
|
518 | 528 | |
|
519 | 529 | def test_assign_magic(): |
|
520 | transform_checker(syntax['assign_magic'], isp.transform_assign_magic) | |
|
530 | tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic']) | |
|
521 | 531 | |
|
522 | 532 | |
|
523 | 533 | def test_classic_prompt(): |
@@ -532,34 +542,34 b' def test_ipy_prompt():' | |||
|
532 | 542 | transform_checker(example, isp.transform_ipy_prompt) |
|
533 | 543 | |
|
534 | 544 | def test_end_help(): |
|
535 | transform_checker(syntax['end_help'], isp.transform_help_end) | |
|
545 | tt.check_pairs(isp.transform_help_end, syntax['end_help']) | |
|
536 | 546 | |
|
537 | 547 | def test_escaped_noesc(): |
|
538 | transform_checker(syntax['escaped_noesc'], isp.transform_escaped) | |
|
548 | tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc']) | |
|
539 | 549 | |
|
540 | 550 | |
|
541 | 551 | def test_escaped_shell(): |
|
542 | transform_checker(syntax['escaped_shell'], isp.transform_escaped) | |
|
552 | tt.check_pairs(isp.transform_escaped, syntax['escaped_shell']) | |
|
543 | 553 | |
|
544 | 554 | |
|
545 | 555 | def test_escaped_help(): |
|
546 | transform_checker(syntax['escaped_help'], isp.transform_escaped) | |
|
556 | tt.check_pairs(isp.transform_escaped, syntax['escaped_help']) | |
|
547 | 557 | |
|
548 | 558 | |
|
549 | 559 | def test_escaped_magic(): |
|
550 | transform_checker(syntax['escaped_magic'], isp.transform_escaped) | |
|
560 | tt.check_pairs(isp.transform_escaped, syntax['escaped_magic']) | |
|
551 | 561 | |
|
552 | 562 | |
|
553 | 563 | def test_escaped_quote(): |
|
554 | transform_checker(syntax['escaped_quote'], isp.transform_escaped) | |
|
564 | tt.check_pairs(isp.transform_escaped, syntax['escaped_quote']) | |
|
555 | 565 | |
|
556 | 566 | |
|
557 | 567 | def test_escaped_quote2(): |
|
558 | transform_checker(syntax['escaped_quote2'], isp.transform_escaped) | |
|
568 | tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2']) | |
|
559 | 569 | |
|
560 | 570 | |
|
561 | 571 | def test_escaped_paren(): |
|
562 | transform_checker(syntax['escaped_paren'], isp.transform_escaped) | |
|
572 | tt.check_pairs(isp.transform_escaped, syntax['escaped_paren']) | |
|
563 | 573 | |
|
564 | 574 | |
|
565 | 575 | class IPythonInputTestCase(InputSplitterTestCase): |
General Comments 0
You need to be logged in to leave comments.
Login now