Show More
@@ -48,7 +48,7 b' def check_cpaste(code, should_fail=False):' | |||||
48 | ip.magic('cpaste') |
|
48 | ip.magic('cpaste') | |
49 |
|
49 | |||
50 | if not should_fail: |
|
50 | if not should_fail: | |
51 | assert ip.user_ns['code_ran'] |
|
51 | assert ip.user_ns['code_ran'], "%r failed" % code | |
52 | finally: |
|
52 | finally: | |
53 | sys.stdin = stdin_save |
|
53 | sys.stdin = stdin_save | |
54 |
|
54 | |||
@@ -130,6 +130,7 b' class PasteTestCase(TestCase):' | |||||
130 |
|
130 | |||
131 | def test_paste_py_multi_r(self): |
|
131 | def test_paste_py_multi_r(self): | |
132 | "Now, test that self.paste -r works" |
|
132 | "Now, test that self.paste -r works" | |
|
133 | self.test_paste_py_multi() | |||
133 | nt.assert_equal(ip.user_ns.pop('x'), [1,2,3]) |
|
134 | nt.assert_equal(ip.user_ns.pop('x'), [1,2,3]) | |
134 | nt.assert_equal(ip.user_ns.pop('y'), [1,4,9]) |
|
135 | nt.assert_equal(ip.user_ns.pop('y'), [1,4,9]) | |
135 | nt.assert_false('x' in ip.user_ns) |
|
136 | nt.assert_false('x' in ip.user_ns) |
@@ -83,69 +83,6 b' class TerminalMagics(Magics):' | |||||
83 | def __init__(self, shell): |
|
83 | def __init__(self, shell): | |
84 | super(TerminalMagics, self).__init__(shell) |
|
84 | super(TerminalMagics, self).__init__(shell) | |
85 | self.input_splitter = IPythonInputSplitter() |
|
85 | self.input_splitter = IPythonInputSplitter() | |
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 |
|
86 | |||
150 | def store_or_execute(self, block, name): |
|
87 | def store_or_execute(self, block, name): | |
151 | """ Execute a block, or store it in a variable, per the user's request. |
|
88 | """ Execute a block, or store it in a variable, per the user's request. | |
@@ -155,13 +92,19 b' class TerminalMagics(Magics):' | |||||
155 | self.shell.user_ns[name] = SList(block.splitlines()) |
|
92 | self.shell.user_ns[name] = SList(block.splitlines()) | |
156 | print("Block assigned to '%s'" % name) |
|
93 | print("Block assigned to '%s'" % name) | |
157 | else: |
|
94 | else: | |
158 | self.shell.user_ns['pasted_block'] = block |
|
95 | b = self.preclean_input(block) | |
159 | b = self.shell.input_transformer_manager.transform_cell(block) |
|
96 | self.shell.user_ns['pasted_block'] = b | |
160 | self.shell.using_paste_magics = True |
|
97 | self.shell.using_paste_magics = True | |
161 | try: |
|
98 | try: | |
162 | self.shell.run_cell(b) |
|
99 | self.shell.run_cell(b) | |
163 | finally: |
|
100 | finally: | |
164 | self.shell.using_paste_magics = False |
|
101 | self.shell.using_paste_magics = False | |
|
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)) | |||
165 |
|
108 | |||
166 | def rerun_pasted(self, name='pasted_block'): |
|
109 | def rerun_pasted(self, name='pasted_block'): | |
167 | """ Rerun a previously pasted command. |
|
110 | """ Rerun a previously pasted command. |
@@ -49,10 +49,6 b' from nose.util import anyp, getpackage, test_address, resolve_name, tolist' | |||||
49 |
|
49 | |||
50 | # Our own imports |
|
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 | # Module globals and other constants |
|
53 | # Module globals and other constants | |
58 | #----------------------------------------------------------------------------- |
|
54 | #----------------------------------------------------------------------------- | |
@@ -386,7 +382,11 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
386 |
|
382 | |||
387 | def ip2py(self,source): |
|
383 | def ip2py(self,source): | |
388 | """Convert input IPython source into valid Python.""" |
|
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 | def parse(self, string, name='<string>'): |
|
391 | def parse(self, string, name='<string>'): | |
392 | """ |
|
392 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now