##// END OF EJS Templates
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
Thomas Kluyver -
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 return _make_help_call(target, esc, lspace)
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