##// END OF EJS Templates
Fix split_user_input to correctly handle %% escape for cell magics.
Fernando Perez -
Show More
@@ -1,137 +1,137 b''
1 1 # encoding: utf-8
2 2 """
3 3 Simple utility for splitting user input. This is used by both inputsplitter and
4 4 prefilter.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import re
24 24 import sys
25 25
26 26 from IPython.utils import py3compat
27 27 from IPython.utils.encoding import get_stream_enc
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Main function
31 31 #-----------------------------------------------------------------------------
32 32
33 33 # RegExp for splitting line contents into pre-char//first word-method//rest.
34 34 # For clarity, each group in on one line.
35 35
36 36 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
37 37 # they are hardwired in.
38 38
39 39 # Although it's not solely driven by the regex, note that:
40 40 # ,;/% only trigger if they are the first character on the line
41 41 # ! and !! trigger if they are first char(s) *or* follow an indent
42 42 # ? triggers as first or last char.
43 43
44 44 line_split = re.compile("""
45 45 ^(\s*) # any leading space
46 46 ([,;/%]|!!?|\?\??)? # escape character or characters
47 \s*(%?[\w\.\*]*) # function/method, possibly with leading %
47 \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading %
48 48 # to correctly treat things like '?%magic'
49 49 (.*?$|$) # rest of line
50 50 """, re.VERBOSE)
51 51
52 52
53 53 def split_user_input(line, pattern=None):
54 54 """Split user input into initial whitespace, escape character, function part
55 55 and the rest.
56 56 """
57 57 # We need to ensure that the rest of this routine deals only with unicode
58 58 encoding = get_stream_enc(sys.stdin, 'utf-8')
59 59 line = py3compat.cast_unicode(line, encoding)
60 60
61 61 if pattern is None:
62 62 pattern = line_split
63 63 match = pattern.match(line)
64 64 if not match:
65 65 # print "match failed for line '%s'" % line
66 66 try:
67 67 ifun, the_rest = line.split(None,1)
68 68 except ValueError:
69 69 # print "split failed for line '%s'" % line
70 70 ifun, the_rest = line, u''
71 71 pre = re.match('^(\s*)(.*)',line).groups()[0]
72 72 esc = ""
73 73 else:
74 74 pre, esc, ifun, the_rest = match.groups()
75 75
76 76 #print 'line:<%s>' % line # dbg
77 77 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
78 78 return pre, esc or '', ifun.strip(), the_rest.lstrip()
79 79
80 80
81 81 class LineInfo(object):
82 82 """A single line of input and associated info.
83 83
84 84 Includes the following as properties:
85 85
86 86 line
87 87 The original, raw line
88 88
89 89 continue_prompt
90 90 Is this line a continuation in a sequence of multiline input?
91 91
92 92 pre
93 93 Any leading whitespace.
94 94
95 95 esc
96 96 The escape character(s) in pre or the empty string if there isn't one.
97 97 Note that '!!' and '??' are possible values for esc. Otherwise it will
98 98 always be a single character.
99 99
100 100 ifun
101 101 The 'function part', which is basically the maximal initial sequence
102 102 of valid python identifiers and the '.' character. This is what is
103 103 checked for alias and magic transformations, used for auto-calling,
104 104 etc. In contrast to Python identifiers, it may start with "%" and contain
105 105 "*".
106 106
107 107 the_rest
108 108 Everything else on the line.
109 109 """
110 110 def __init__(self, line, continue_prompt=False):
111 111 self.line = line
112 112 self.continue_prompt = continue_prompt
113 113 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
114 114
115 115 self.pre_char = self.pre.strip()
116 116 if self.pre_char:
117 117 self.pre_whitespace = '' # No whitespace allowd before esc chars
118 118 else:
119 119 self.pre_whitespace = self.pre
120 120
121 121 def ofind(self, ip):
122 122 """Do a full, attribute-walking lookup of the ifun in the various
123 123 namespaces for the given IPython InteractiveShell instance.
124 124
125 125 Return a dict with keys: {found, obj, ospace, ismagic}
126 126
127 127 Note: can cause state changes because of calling getattr, but should
128 128 only be run if autocall is on and if the line hasn't matched any
129 129 other, less dangerous handlers.
130 130
131 131 Does cache the results of the call, so can be called multiple times
132 132 without worrying about *further* damaging state.
133 133 """
134 134 return ip._ofind(self.ifun)
135 135
136 136 def __str__(self):
137 137 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -1,32 +1,35 b''
1 1 # coding: utf-8
2 2 from IPython.core.splitinput import split_user_input
3 3 from IPython.testing import tools as tt
4 4 from IPython.utils import py3compat
5 5
6 6 tests = [
7 7 ('x=1', ('', '', 'x', '=1')),
8 8 ('?', ('', '?', '', '')),
9 9 ('??', ('', '??', '', '')),
10 10 (' ?', (' ', '?', '', '')),
11 11 (' ??', (' ', '??', '', '')),
12 12 ('??x', ('', '??', 'x', '')),
13 13 ('?x=1', ('', '?', 'x', '=1')),
14 14 ('!ls', ('', '!', 'ls', '')),
15 15 (' !ls', (' ', '!', 'ls', '')),
16 16 ('!!ls', ('', '!!', 'ls', '')),
17 17 (' !!ls', (' ', '!!', 'ls', '')),
18 18 (',ls', ('', ',', 'ls', '')),
19 19 (';ls', ('', ';', 'ls', '')),
20 20 (' ;ls', (' ', ';', 'ls', '')),
21 21 ('f.g(x)', ('', '', 'f.g', '(x)')),
22 22 ('f.g (x)', ('', '', 'f.g', '(x)')),
23 ('?%hist', ('', '?', '%hist', '')),
23 ('?%hist1', ('', '?', '%hist1', '')),
24 ('?%%hist2', ('', '?', '%%hist2', '')),
25 ('??%hist3', ('', '??', '%hist3', '')),
26 ('??%%hist4', ('', '??', '%%hist4', '')),
24 27 ('?x*', ('', '?', 'x*', '')),
25 28 ]
26 29 if py3compat.PY3:
27 30 tests.append((u"Pérez Fernando", (u'', u'', u'Pérez', u'Fernando')))
28 31 else:
29 32 tests.append((u"Pérez Fernando", (u'', u'', u'P', u'érez Fernando')))
30 33
31 34 def test_split_user_input():
32 35 return tt.check_pairs(split_user_input, tests)
General Comments 0
You need to be logged in to leave comments. Login now