##// END OF EJS Templates
Add transformation for system assignments
Thomas Kluyver -
Show More
@@ -137,6 +137,57 b' class MagicAssign:'
137
137
138 return lines_before + [new_line] + lines_after
138 return lines_before + [new_line] + lines_after
139
139
140
141 class SystemAssign:
142 @staticmethod
143 def find(tokens_by_line):
144 """Find the first system assignment (a = !foo) in the cell.
145
146 Returns (line, column) of the ! if found, or None.
147 """
148 for line in tokens_by_line:
149 assign_ix = _find_assign_op(line)
150 if (assign_ix is not None) \
151 and (len(line) >= assign_ix + 2) \
152 and (line[assign_ix + 1].type == tokenize2.ERRORTOKEN):
153 ix = assign_ix + 1
154
155 while ix < len(line) and line[ix].type == tokenize2.ERRORTOKEN:
156 if line[ix].string == '!':
157 return line[ix].start
158 elif not line[ix].string.isspace():
159 break
160 ix += 1
161
162 @staticmethod
163 def transform(lines: List[str], start: Tuple[int, int]):
164 """Transform a system assignment found by find
165 """
166 start_line = start[0] - 1 # Shift from 1-index to 0-index
167 start_col = start[1]
168
169 print("Start at", start_line, start_col)
170 print("Line", lines[start_line])
171
172 lhs, rhs = lines[start_line][:start_col], lines[start_line][
173 start_col:-1]
174 assert rhs.startswith('!'), rhs
175 cmd_parts = [rhs[1:]]
176 end_line = start_line
177 # Follow explicit (backslash) line continuations
178 while end_line < len(lines) and cmd_parts[-1].endswith('\\'):
179 end_line += 1
180 cmd_parts[-1] = cmd_parts[-1][:-1] # Trim backslash
181 cmd_parts.append(lines[end_line][:-1]) # Trim newline
182 cmd = ' '.join(cmd_parts)
183
184 lines_before = lines[:start_line]
185 call = "get_ipython().getoutput({!r})".format(cmd)
186 new_line = lhs + call + '\n'
187 lines_after = lines[end_line + 1:]
188
189 return lines_before + [new_line] + lines_after
190
140 def make_tokens_by_line(lines):
191 def make_tokens_by_line(lines):
141 tokens_by_line = [[]]
192 tokens_by_line = [[]]
142 for token in generate_tokens(iter(lines).__next__):
193 for token in generate_tokens(iter(lines).__next__):
@@ -149,7 +200,8 b' def make_tokens_by_line(lines):'
149 class TokenTransformers:
200 class TokenTransformers:
150 def __init__(self):
201 def __init__(self):
151 self.transformers = [
202 self.transformers = [
152 MagicAssign
203 MagicAssign,
204 SystemAssign,
153 ]
205 ]
154
206
155 def do_one_transform(self, lines):
207 def do_one_transform(self, lines):
@@ -1,6 +1,6 b''
1 import nose.tools as nt
1 import nose.tools as nt
2
2
3 from IPython.core import inputtransformer2
3 from IPython.core import inputtransformer2 as ipt2
4 from IPython.core.inputtransformer2 import make_tokens_by_line
4 from IPython.core.inputtransformer2 import make_tokens_by_line
5
5
6 MULTILINE_MAGIC_ASSIGN = ("""\
6 MULTILINE_MAGIC_ASSIGN = ("""\
@@ -21,17 +21,34 b' b = !foo \\\\'
21 g()
21 g()
22 """.splitlines(keepends=True), """\
22 """.splitlines(keepends=True), """\
23 a = f()
23 a = f()
24 b = get_ipython().getoutput('foo bar')
24 b = get_ipython().getoutput('foo bar')
25 g()
25 g()
26 """.splitlines(keepends=True))
26 """.splitlines(keepends=True))
27
27
28 def test_find_assign_magic():
28 def test_find_assign_magic():
29 tbl = make_tokens_by_line(MULTILINE_MAGIC_ASSIGN[0])
29 tbl = make_tokens_by_line(MULTILINE_MAGIC_ASSIGN[0])
30 nt.assert_equal(inputtransformer2.MagicAssign.find(tbl), (2, 4))
30 nt.assert_equal(ipt2.MagicAssign.find(tbl), (2, 4))
31
31
32 tbl = make_tokens_by_line(MULTILINE_SYSTEM_ASSIGN[0]) # Nothing to find
32 tbl = make_tokens_by_line(MULTILINE_SYSTEM_ASSIGN[0]) # Nothing to find
33 nt.assert_equal(inputtransformer2.MagicAssign.find(tbl), None)
33 nt.assert_equal(ipt2.MagicAssign.find(tbl), None)
34
34
35 def test_transform_assign_magic():
35 def test_transform_assign_magic():
36 res = inputtransformer2.MagicAssign.transform(MULTILINE_MAGIC_ASSIGN[0], (2, 4))
36 res = ipt2.MagicAssign.transform(MULTILINE_MAGIC_ASSIGN[0], (2, 4))
37 nt.assert_equal(res, MULTILINE_MAGIC_ASSIGN[1])
37 nt.assert_equal(res, MULTILINE_MAGIC_ASSIGN[1])
38
39 def test_find_assign_system():
40 tbl = make_tokens_by_line(MULTILINE_SYSTEM_ASSIGN[0])
41 nt.assert_equal(ipt2.SystemAssign.find(tbl), (2, 4))
42
43 tbl = make_tokens_by_line(["a = !ls\n"])
44 nt.assert_equal(ipt2.SystemAssign.find(tbl), (1, 5))
45
46 tbl = make_tokens_by_line(["a=!ls\n"])
47 nt.assert_equal(ipt2.SystemAssign.find(tbl), (1, 2))
48
49 tbl = make_tokens_by_line(MULTILINE_MAGIC_ASSIGN[0]) # Nothing to find
50 nt.assert_equal(ipt2.SystemAssign.find(tbl), None)
51
52 def test_transform_assign_system():
53 res = ipt2.SystemAssign.transform(MULTILINE_SYSTEM_ASSIGN[0], (2, 4))
54 nt.assert_equal(res, MULTILINE_SYSTEM_ASSIGN[1])
General Comments 0
You need to be logged in to leave comments. Login now