##// END OF EJS Templates
Refactor paste magics and ipdoctest
Thomas Kluyver -
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