Show More
@@ -48,7 +48,7 b' def check_cpaste(code, should_fail=False):' | |||
|
48 | 48 | ip.magic('cpaste') |
|
49 | 49 | |
|
50 | 50 | if not should_fail: |
|
51 | assert ip.user_ns['code_ran'] | |
|
51 | assert ip.user_ns['code_ran'], "%r failed" % code | |
|
52 | 52 | finally: |
|
53 | 53 | sys.stdin = stdin_save |
|
54 | 54 | |
@@ -130,6 +130,7 b' class PasteTestCase(TestCase):' | |||
|
130 | 130 | |
|
131 | 131 | def test_paste_py_multi_r(self): |
|
132 | 132 | "Now, test that self.paste -r works" |
|
133 | self.test_paste_py_multi() | |
|
133 | 134 | nt.assert_equal(ip.user_ns.pop('x'), [1,2,3]) |
|
134 | 135 | nt.assert_equal(ip.user_ns.pop('y'), [1,4,9]) |
|
135 | 136 | nt.assert_false('x' in ip.user_ns) |
@@ -84,69 +84,6 b' class TerminalMagics(Magics):' | |||
|
84 | 84 | super(TerminalMagics, self).__init__(shell) |
|
85 | 85 | self.input_splitter = IPythonInputSplitter() |
|
86 | 86 | |
|
87 | def cleanup_input(self, block): | |
|
88 | """Apply all possible IPython cleanups to an input block. | |
|
89 | ||
|
90 | This means: | |
|
91 | ||
|
92 | - remove any global leading whitespace (dedent) | |
|
93 | - remove any email quotes ('>') if they are present in *all* lines | |
|
94 | - apply all static inputsplitter transforms and break into sub-blocks | |
|
95 | - apply prefilter() to each sub-block that is a single line. | |
|
96 | ||
|
97 | Parameters | |
|
98 | ---------- | |
|
99 | block : str | |
|
100 | A possibly multiline input string of code. | |
|
101 | ||
|
102 | Returns | |
|
103 | ------- | |
|
104 | transformed block : str | |
|
105 | The input, with all transformations above applied. | |
|
106 | """ | |
|
107 | # We have to effectively implement client-side the loop that is done by | |
|
108 | # the terminal frontend, and furthermore do it on a block that can | |
|
109 | # possibly contain multiple statments pasted in one go. | |
|
110 | ||
|
111 | # First, run the input through the block splitting code. We should | |
|
112 | # eventually make this a self-contained method in the inputsplitter. | |
|
113 | isp = self.input_splitter | |
|
114 | isp.reset() | |
|
115 | b = textwrap.dedent(block) | |
|
116 | ||
|
117 | # Remove email quotes first. These must be consistently applied to | |
|
118 | # *all* lines to be removed | |
|
119 | b = strip_email_quotes(b) | |
|
120 | ||
|
121 | # Split the input into independent sub-blocks so we can later do | |
|
122 | # prefiltering (which must be done *only* to single-line inputs) | |
|
123 | blocks = [] | |
|
124 | last_block = [] | |
|
125 | for line in b.splitlines(): | |
|
126 | isp.push(line) | |
|
127 | last_block.append(line) | |
|
128 | if not isp.push_accepts_more(): | |
|
129 | blocks.append(isp.source_reset()) | |
|
130 | last_block = [] | |
|
131 | if last_block: | |
|
132 | blocks.append('\n'.join(last_block)) | |
|
133 | ||
|
134 | # Now, apply prefiltering to any one-line block to match the behavior | |
|
135 | # of the interactive terminal | |
|
136 | final_blocks = [] | |
|
137 | for block in blocks: | |
|
138 | lines = block.splitlines() | |
|
139 | if len(lines) == 1: | |
|
140 | final_blocks.append(self.shell.prefilter(lines[0])) | |
|
141 | else: | |
|
142 | final_blocks.append(block) | |
|
143 | ||
|
144 | # We now have the final version of the input code as a list of blocks, | |
|
145 | # with all inputsplitter transformations applied and single-line blocks | |
|
146 | # run through prefilter. For further processing, turn into a single | |
|
147 | # string as the rest of our apis use string inputs. | |
|
148 | return '\n'.join(final_blocks) | |
|
149 | ||
|
150 | 87 | def store_or_execute(self, block, name): |
|
151 | 88 | """ Execute a block, or store it in a variable, per the user's request. |
|
152 | 89 | """ |
@@ -155,14 +92,20 b' class TerminalMagics(Magics):' | |||
|
155 | 92 | self.shell.user_ns[name] = SList(block.splitlines()) |
|
156 | 93 | print("Block assigned to '%s'" % name) |
|
157 | 94 | else: |
|
158 | self.shell.user_ns['pasted_block'] = block | |
|
159 | b = self.shell.input_transformer_manager.transform_cell(block) | |
|
95 | b = self.preclean_input(block) | |
|
96 | self.shell.user_ns['pasted_block'] = b | |
|
160 | 97 | self.shell.using_paste_magics = True |
|
161 | 98 | try: |
|
162 | 99 | self.shell.run_cell(b) |
|
163 | 100 | finally: |
|
164 | 101 | self.shell.using_paste_magics = False |
|
165 | 102 | |
|
103 | def preclean_input(self, block): | |
|
104 | lines = block.splitlines() | |
|
105 | while lines and not lines[0].strip(): | |
|
106 | lines = lines[1:] | |
|
107 | return strip_email_quotes('\n'.join(lines)) | |
|
108 | ||
|
166 | 109 | def rerun_pasted(self, name='pasted_block'): |
|
167 | 110 | """ Rerun a previously pasted command. |
|
168 | 111 | """ |
@@ -49,10 +49,6 b' from nose.util import anyp, getpackage, test_address, resolve_name, tolist' | |||
|
49 | 49 | |
|
50 | 50 | # Our own imports |
|
51 | 51 | |
|
52 | # We're temporarily using TerminalMagics.cleanup_input() until the functionality | |
|
53 | # is moved into core. | |
|
54 | from IPython.frontend.terminal.interactiveshell import TerminalMagics | |
|
55 | ||
|
56 | 52 | #----------------------------------------------------------------------------- |
|
57 | 53 | # Module globals and other constants |
|
58 | 54 | #----------------------------------------------------------------------------- |
@@ -386,7 +382,11 b' class IPDocTestParser(doctest.DocTestParser):' | |||
|
386 | 382 | |
|
387 | 383 | def ip2py(self,source): |
|
388 | 384 | """Convert input IPython source into valid Python.""" |
|
389 | return TerminalMagics(_ip).cleanup_input(source) | |
|
385 | block = _ip.input_transformer_manager.transform_cell(source) | |
|
386 | if len(block.splitlines()) == 1: | |
|
387 | return _ip.prefilter(block) | |
|
388 | else: | |
|
389 | return block | |
|
390 | 390 | |
|
391 | 391 | def parse(self, string, name='<string>'): |
|
392 | 392 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now