##// 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 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