##// END OF EJS Templates
Add a transform_cell convenience method to the inputsplitter object.
Fernando Perez -
Show More
@@ -1,903 +1,910 b''
1 """Analysis of text input into executable blocks.
1 """Analysis of text input into executable blocks.
2
2
3 The main class in this module, :class:`InputSplitter`, is designed to break
3 The main class in this module, :class:`InputSplitter`, is designed to break
4 input from either interactive, line-by-line environments or block-based ones,
4 input from either interactive, line-by-line environments or block-based ones,
5 into standalone blocks that can be executed by Python as 'single' statements
5 into standalone blocks that can be executed by Python as 'single' statements
6 (thus triggering sys.displayhook).
6 (thus triggering sys.displayhook).
7
7
8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
9 with full support for the extended IPython syntax (magics, system calls, etc).
9 with full support for the extended IPython syntax (magics, system calls, etc).
10
10
11 For more details, see the class docstring below.
11 For more details, see the class docstring below.
12
12
13 Syntax Transformations
13 Syntax Transformations
14 ----------------------
14 ----------------------
15
15
16 One of the main jobs of the code in this file is to apply all syntax
16 One of the main jobs of the code in this file is to apply all syntax
17 transformations that make up 'the IPython language', i.e. magics, shell
17 transformations that make up 'the IPython language', i.e. magics, shell
18 escapes, etc. All transformations should be implemented as *fully stateless*
18 escapes, etc. All transformations should be implemented as *fully stateless*
19 entities, that simply take one line as their input and return a line.
19 entities, that simply take one line as their input and return a line.
20 Internally for implementation purposes they may be a normal function or a
20 Internally for implementation purposes they may be a normal function or a
21 callable object, but the only input they receive will be a single line and they
21 callable object, but the only input they receive will be a single line and they
22 should only return a line, without holding any data-dependent state between
22 should only return a line, without holding any data-dependent state between
23 calls.
23 calls.
24
24
25 As an example, the EscapedTransformer is a class so we can more clearly group
25 As an example, the EscapedTransformer is a class so we can more clearly group
26 together the functionality of dispatching to individual functions based on the
26 together the functionality of dispatching to individual functions based on the
27 starting escape character, but the only method for public use is its call
27 starting escape character, but the only method for public use is its call
28 method.
28 method.
29
29
30
30
31 ToDo
31 ToDo
32 ----
32 ----
33
33
34 - Should we make push() actually raise an exception once push_accepts_more()
34 - Should we make push() actually raise an exception once push_accepts_more()
35 returns False?
35 returns False?
36
36
37 - Naming cleanups. The tr_* names aren't the most elegant, though now they are
37 - Naming cleanups. The tr_* names aren't the most elegant, though now they are
38 at least just attributes of a class so not really very exposed.
38 at least just attributes of a class so not really very exposed.
39
39
40 - Think about the best way to support dynamic things: automagic, autocall,
40 - Think about the best way to support dynamic things: automagic, autocall,
41 macros, etc.
41 macros, etc.
42
42
43 - Think of a better heuristic for the application of the transforms in
43 - Think of a better heuristic for the application of the transforms in
44 IPythonInputSplitter.push() than looking at the buffer ending in ':'. Idea:
44 IPythonInputSplitter.push() than looking at the buffer ending in ':'. Idea:
45 track indentation change events (indent, dedent, nothing) and apply them only
45 track indentation change events (indent, dedent, nothing) and apply them only
46 if the indentation went up, but not otherwise.
46 if the indentation went up, but not otherwise.
47
47
48 - Think of the cleanest way for supporting user-specified transformations (the
48 - Think of the cleanest way for supporting user-specified transformations (the
49 user prefilters we had before).
49 user prefilters we had before).
50
50
51 Authors
51 Authors
52 -------
52 -------
53
53
54 * Fernando Perez
54 * Fernando Perez
55 * Brian Granger
55 * Brian Granger
56 """
56 """
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58 # Copyright (C) 2010 The IPython Development Team
58 # Copyright (C) 2010 The IPython Development Team
59 #
59 #
60 # Distributed under the terms of the BSD License. The full license is in
60 # Distributed under the terms of the BSD License. The full license is in
61 # the file COPYING, distributed as part of this software.
61 # the file COPYING, distributed as part of this software.
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Imports
65 # Imports
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
67 # stdlib
67 # stdlib
68 import ast
68 import ast
69 import codeop
69 import codeop
70 import re
70 import re
71 import sys
71 import sys
72 import tokenize
72 import tokenize
73 from StringIO import StringIO
73 from StringIO import StringIO
74
74
75 # IPython modules
75 # IPython modules
76 from IPython.core.splitinput import split_user_input, LineInfo
76 from IPython.core.splitinput import split_user_input, LineInfo
77 from IPython.utils.py3compat import cast_unicode
77 from IPython.utils.py3compat import cast_unicode
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Globals
80 # Globals
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 # The escape sequences that define the syntax transformations IPython will
83 # The escape sequences that define the syntax transformations IPython will
84 # apply to user input. These can NOT be just changed here: many regular
84 # apply to user input. These can NOT be just changed here: many regular
85 # expressions and other parts of the code may use their hardcoded values, and
85 # expressions and other parts of the code may use their hardcoded values, and
86 # for all intents and purposes they constitute the 'IPython syntax', so they
86 # for all intents and purposes they constitute the 'IPython syntax', so they
87 # should be considered fixed.
87 # should be considered fixed.
88
88
89 ESC_SHELL = '!' # Send line to underlying system shell
89 ESC_SHELL = '!' # Send line to underlying system shell
90 ESC_SH_CAP = '!!' # Send line to system shell and capture output
90 ESC_SH_CAP = '!!' # Send line to system shell and capture output
91 ESC_HELP = '?' # Find information about object
91 ESC_HELP = '?' # Find information about object
92 ESC_HELP2 = '??' # Find extra-detailed information about object
92 ESC_HELP2 = '??' # Find extra-detailed information about object
93 ESC_MAGIC = '%' # Call magic function
93 ESC_MAGIC = '%' # Call magic function
94 ESC_MAGIC2 = '%%' # Call cell-magic function
94 ESC_MAGIC2 = '%%' # Call cell-magic function
95 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
95 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
96 ESC_QUOTE2 = ';' # Quote all args as a single string, call
96 ESC_QUOTE2 = ';' # Quote all args as a single string, call
97 ESC_PAREN = '/' # Call first argument with rest of line as arguments
97 ESC_PAREN = '/' # Call first argument with rest of line as arguments
98
98
99 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
100 # Utilities
100 # Utilities
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102
102
103 # FIXME: These are general-purpose utilities that later can be moved to the
103 # FIXME: These are general-purpose utilities that later can be moved to the
104 # general ward. Kept here for now because we're being very strict about test
104 # general ward. Kept here for now because we're being very strict about test
105 # coverage with this code, and this lets us ensure that we keep 100% coverage
105 # coverage with this code, and this lets us ensure that we keep 100% coverage
106 # while developing.
106 # while developing.
107
107
108 # compiled regexps for autoindent management
108 # compiled regexps for autoindent management
109 dedent_re = re.compile('|'.join([
109 dedent_re = re.compile('|'.join([
110 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
110 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
111 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
111 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
112 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
112 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
113 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
113 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
114 r'^\s+pass\s*$' # pass (optionally followed by trailing spaces)
114 r'^\s+pass\s*$' # pass (optionally followed by trailing spaces)
115 ]))
115 ]))
116 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
116 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
117
117
118 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
118 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
119 # before pure comments
119 # before pure comments
120 comment_line_re = re.compile('^\s*\#')
120 comment_line_re = re.compile('^\s*\#')
121
121
122
122
123 def num_ini_spaces(s):
123 def num_ini_spaces(s):
124 """Return the number of initial spaces in a string.
124 """Return the number of initial spaces in a string.
125
125
126 Note that tabs are counted as a single space. For now, we do *not* support
126 Note that tabs are counted as a single space. For now, we do *not* support
127 mixing of tabs and spaces in the user's input.
127 mixing of tabs and spaces in the user's input.
128
128
129 Parameters
129 Parameters
130 ----------
130 ----------
131 s : string
131 s : string
132
132
133 Returns
133 Returns
134 -------
134 -------
135 n : int
135 n : int
136 """
136 """
137
137
138 ini_spaces = ini_spaces_re.match(s)
138 ini_spaces = ini_spaces_re.match(s)
139 if ini_spaces:
139 if ini_spaces:
140 return ini_spaces.end()
140 return ini_spaces.end()
141 else:
141 else:
142 return 0
142 return 0
143
143
144 def last_blank(src):
144 def last_blank(src):
145 """Determine if the input source ends in a blank.
145 """Determine if the input source ends in a blank.
146
146
147 A blank is either a newline or a line consisting of whitespace.
147 A blank is either a newline or a line consisting of whitespace.
148
148
149 Parameters
149 Parameters
150 ----------
150 ----------
151 src : string
151 src : string
152 A single or multiline string.
152 A single or multiline string.
153 """
153 """
154 if not src: return False
154 if not src: return False
155 ll = src.splitlines()[-1]
155 ll = src.splitlines()[-1]
156 return (ll == '') or ll.isspace()
156 return (ll == '') or ll.isspace()
157
157
158
158
159 last_two_blanks_re = re.compile(r'\n\s*\n\s*$', re.MULTILINE)
159 last_two_blanks_re = re.compile(r'\n\s*\n\s*$', re.MULTILINE)
160 last_two_blanks_re2 = re.compile(r'.+\n\s*\n\s+$', re.MULTILINE)
160 last_two_blanks_re2 = re.compile(r'.+\n\s*\n\s+$', re.MULTILINE)
161
161
162 def last_two_blanks(src):
162 def last_two_blanks(src):
163 """Determine if the input source ends in two blanks.
163 """Determine if the input source ends in two blanks.
164
164
165 A blank is either a newline or a line consisting of whitespace.
165 A blank is either a newline or a line consisting of whitespace.
166
166
167 Parameters
167 Parameters
168 ----------
168 ----------
169 src : string
169 src : string
170 A single or multiline string.
170 A single or multiline string.
171 """
171 """
172 if not src: return False
172 if not src: return False
173 # The logic here is tricky: I couldn't get a regexp to work and pass all
173 # The logic here is tricky: I couldn't get a regexp to work and pass all
174 # the tests, so I took a different approach: split the source by lines,
174 # the tests, so I took a different approach: split the source by lines,
175 # grab the last two and prepend '###\n' as a stand-in for whatever was in
175 # grab the last two and prepend '###\n' as a stand-in for whatever was in
176 # the body before the last two lines. Then, with that structure, it's
176 # the body before the last two lines. Then, with that structure, it's
177 # possible to analyze with two regexps. Not the most elegant solution, but
177 # possible to analyze with two regexps. Not the most elegant solution, but
178 # it works. If anyone tries to change this logic, make sure to validate
178 # it works. If anyone tries to change this logic, make sure to validate
179 # the whole test suite first!
179 # the whole test suite first!
180 new_src = '\n'.join(['###\n'] + src.splitlines()[-2:])
180 new_src = '\n'.join(['###\n'] + src.splitlines()[-2:])
181 return (bool(last_two_blanks_re.match(new_src)) or
181 return (bool(last_two_blanks_re.match(new_src)) or
182 bool(last_two_blanks_re2.match(new_src)) )
182 bool(last_two_blanks_re2.match(new_src)) )
183
183
184
184
185 def remove_comments(src):
185 def remove_comments(src):
186 """Remove all comments from input source.
186 """Remove all comments from input source.
187
187
188 Note: comments are NOT recognized inside of strings!
188 Note: comments are NOT recognized inside of strings!
189
189
190 Parameters
190 Parameters
191 ----------
191 ----------
192 src : string
192 src : string
193 A single or multiline input string.
193 A single or multiline input string.
194
194
195 Returns
195 Returns
196 -------
196 -------
197 String with all Python comments removed.
197 String with all Python comments removed.
198 """
198 """
199
199
200 return re.sub('#.*', '', src)
200 return re.sub('#.*', '', src)
201
201
202 def has_comment(src):
202 def has_comment(src):
203 """Indicate whether an input line has (i.e. ends in, or is) a comment.
203 """Indicate whether an input line has (i.e. ends in, or is) a comment.
204
204
205 This uses tokenize, so it can distinguish comments from # inside strings.
205 This uses tokenize, so it can distinguish comments from # inside strings.
206
206
207 Parameters
207 Parameters
208 ----------
208 ----------
209 src : string
209 src : string
210 A single line input string.
210 A single line input string.
211
211
212 Returns
212 Returns
213 -------
213 -------
214 Boolean: True if source has a comment.
214 Boolean: True if source has a comment.
215 """
215 """
216 readline = StringIO(src).readline
216 readline = StringIO(src).readline
217 toktypes = set()
217 toktypes = set()
218 try:
218 try:
219 for t in tokenize.generate_tokens(readline):
219 for t in tokenize.generate_tokens(readline):
220 toktypes.add(t[0])
220 toktypes.add(t[0])
221 except tokenize.TokenError:
221 except tokenize.TokenError:
222 pass
222 pass
223 return(tokenize.COMMENT in toktypes)
223 return(tokenize.COMMENT in toktypes)
224
224
225
225
226 def get_input_encoding():
226 def get_input_encoding():
227 """Return the default standard input encoding.
227 """Return the default standard input encoding.
228
228
229 If sys.stdin has no encoding, 'ascii' is returned."""
229 If sys.stdin has no encoding, 'ascii' is returned."""
230 # There are strange environments for which sys.stdin.encoding is None. We
230 # There are strange environments for which sys.stdin.encoding is None. We
231 # ensure that a valid encoding is returned.
231 # ensure that a valid encoding is returned.
232 encoding = getattr(sys.stdin, 'encoding', None)
232 encoding = getattr(sys.stdin, 'encoding', None)
233 if encoding is None:
233 if encoding is None:
234 encoding = 'ascii'
234 encoding = 'ascii'
235 return encoding
235 return encoding
236
236
237 #-----------------------------------------------------------------------------
237 #-----------------------------------------------------------------------------
238 # Classes and functions for normal Python syntax handling
238 # Classes and functions for normal Python syntax handling
239 #-----------------------------------------------------------------------------
239 #-----------------------------------------------------------------------------
240
240
241 class InputSplitter(object):
241 class InputSplitter(object):
242 """An object that can accumulate lines of Python source before execution.
242 """An object that can accumulate lines of Python source before execution.
243
243
244 This object is designed to be fed python source line-by-line, using
244 This object is designed to be fed python source line-by-line, using
245 :meth:`push`. It will return on each push whether the currently pushed
245 :meth:`push`. It will return on each push whether the currently pushed
246 code could be executed already. In addition, it provides a method called
246 code could be executed already. In addition, it provides a method called
247 :meth:`push_accepts_more` that can be used to query whether more input
247 :meth:`push_accepts_more` that can be used to query whether more input
248 can be pushed into a single interactive block.
248 can be pushed into a single interactive block.
249
249
250 This is a simple example of how an interactive terminal-based client can use
250 This is a simple example of how an interactive terminal-based client can use
251 this tool::
251 this tool::
252
252
253 isp = InputSplitter()
253 isp = InputSplitter()
254 while isp.push_accepts_more():
254 while isp.push_accepts_more():
255 indent = ' '*isp.indent_spaces
255 indent = ' '*isp.indent_spaces
256 prompt = '>>> ' + indent
256 prompt = '>>> ' + indent
257 line = indent + raw_input(prompt)
257 line = indent + raw_input(prompt)
258 isp.push(line)
258 isp.push(line)
259 print 'Input source was:\n', isp.source_reset(),
259 print 'Input source was:\n', isp.source_reset(),
260 """
260 """
261 # Number of spaces of indentation computed from input that has been pushed
261 # Number of spaces of indentation computed from input that has been pushed
262 # so far. This is the attributes callers should query to get the current
262 # so far. This is the attributes callers should query to get the current
263 # indentation level, in order to provide auto-indent facilities.
263 # indentation level, in order to provide auto-indent facilities.
264 indent_spaces = 0
264 indent_spaces = 0
265 # String, indicating the default input encoding. It is computed by default
265 # String, indicating the default input encoding. It is computed by default
266 # at initialization time via get_input_encoding(), but it can be reset by a
266 # at initialization time via get_input_encoding(), but it can be reset by a
267 # client with specific knowledge of the encoding.
267 # client with specific knowledge of the encoding.
268 encoding = ''
268 encoding = ''
269 # String where the current full source input is stored, properly encoded.
269 # String where the current full source input is stored, properly encoded.
270 # Reading this attribute is the normal way of querying the currently pushed
270 # Reading this attribute is the normal way of querying the currently pushed
271 # source code, that has been properly encoded.
271 # source code, that has been properly encoded.
272 source = ''
272 source = ''
273 # Code object corresponding to the current source. It is automatically
273 # Code object corresponding to the current source. It is automatically
274 # synced to the source, so it can be queried at any time to obtain the code
274 # synced to the source, so it can be queried at any time to obtain the code
275 # object; it will be None if the source doesn't compile to valid Python.
275 # object; it will be None if the source doesn't compile to valid Python.
276 code = None
276 code = None
277 # Input mode
277 # Input mode
278 input_mode = 'line'
278 input_mode = 'line'
279
279
280 # Private attributes
280 # Private attributes
281
281
282 # List with lines of input accumulated so far
282 # List with lines of input accumulated so far
283 _buffer = None
283 _buffer = None
284 # Command compiler
284 # Command compiler
285 _compile = None
285 _compile = None
286 # Mark when input has changed indentation all the way back to flush-left
286 # Mark when input has changed indentation all the way back to flush-left
287 _full_dedent = False
287 _full_dedent = False
288 # Boolean indicating whether the current block is complete
288 # Boolean indicating whether the current block is complete
289 _is_complete = None
289 _is_complete = None
290
290
291 def __init__(self, input_mode=None):
291 def __init__(self, input_mode=None):
292 """Create a new InputSplitter instance.
292 """Create a new InputSplitter instance.
293
293
294 Parameters
294 Parameters
295 ----------
295 ----------
296 input_mode : str
296 input_mode : str
297
297
298 One of ['line', 'cell']; default is 'line'.
298 One of ['line', 'cell']; default is 'line'.
299
299
300 The input_mode parameter controls how new inputs are used when fed via
300 The input_mode parameter controls how new inputs are used when fed via
301 the :meth:`push` method:
301 the :meth:`push` method:
302
302
303 - 'line': meant for line-oriented clients, inputs are appended one at a
303 - 'line': meant for line-oriented clients, inputs are appended one at a
304 time to the internal buffer and the whole buffer is compiled.
304 time to the internal buffer and the whole buffer is compiled.
305
305
306 - 'cell': meant for clients that can edit multi-line 'cells' of text at
306 - 'cell': meant for clients that can edit multi-line 'cells' of text at
307 a time. A cell can contain one or more blocks that can be compile in
307 a time. A cell can contain one or more blocks that can be compile in
308 'single' mode by Python. In this mode, each new input new input
308 'single' mode by Python. In this mode, each new input new input
309 completely replaces all prior inputs. Cell mode is thus equivalent
309 completely replaces all prior inputs. Cell mode is thus equivalent
310 to prepending a full reset() to every push() call.
310 to prepending a full reset() to every push() call.
311 """
311 """
312 self._buffer = []
312 self._buffer = []
313 self._compile = codeop.CommandCompiler()
313 self._compile = codeop.CommandCompiler()
314 self.encoding = get_input_encoding()
314 self.encoding = get_input_encoding()
315 self.input_mode = InputSplitter.input_mode if input_mode is None \
315 self.input_mode = InputSplitter.input_mode if input_mode is None \
316 else input_mode
316 else input_mode
317
317
318 def reset(self):
318 def reset(self):
319 """Reset the input buffer and associated state."""
319 """Reset the input buffer and associated state."""
320 self.indent_spaces = 0
320 self.indent_spaces = 0
321 self._buffer[:] = []
321 self._buffer[:] = []
322 self.source = ''
322 self.source = ''
323 self.code = None
323 self.code = None
324 self._is_complete = False
324 self._is_complete = False
325 self._full_dedent = False
325 self._full_dedent = False
326
326
327 def source_reset(self):
327 def source_reset(self):
328 """Return the input source and perform a full reset.
328 """Return the input source and perform a full reset.
329 """
329 """
330 out = self.source
330 out = self.source
331 self.reset()
331 self.reset()
332 return out
332 return out
333
333
334 def push(self, lines):
334 def push(self, lines):
335 """Push one or more lines of input.
335 """Push one or more lines of input.
336
336
337 This stores the given lines and returns a status code indicating
337 This stores the given lines and returns a status code indicating
338 whether the code forms a complete Python block or not.
338 whether the code forms a complete Python block or not.
339
339
340 Any exceptions generated in compilation are swallowed, but if an
340 Any exceptions generated in compilation are swallowed, but if an
341 exception was produced, the method returns True.
341 exception was produced, the method returns True.
342
342
343 Parameters
343 Parameters
344 ----------
344 ----------
345 lines : string
345 lines : string
346 One or more lines of Python input.
346 One or more lines of Python input.
347
347
348 Returns
348 Returns
349 -------
349 -------
350 is_complete : boolean
350 is_complete : boolean
351 True if the current input source (the result of the current input
351 True if the current input source (the result of the current input
352 plus prior inputs) forms a complete Python execution block. Note that
352 plus prior inputs) forms a complete Python execution block. Note that
353 this value is also stored as a private attribute (_is_complete), so it
353 this value is also stored as a private attribute (_is_complete), so it
354 can be queried at any time.
354 can be queried at any time.
355 """
355 """
356 if self.input_mode == 'cell':
356 if self.input_mode == 'cell':
357 self.reset()
357 self.reset()
358
358
359 self._store(lines)
359 self._store(lines)
360 source = self.source
360 source = self.source
361
361
362 # Before calling _compile(), reset the code object to None so that if an
362 # Before calling _compile(), reset the code object to None so that if an
363 # exception is raised in compilation, we don't mislead by having
363 # exception is raised in compilation, we don't mislead by having
364 # inconsistent code/source attributes.
364 # inconsistent code/source attributes.
365 self.code, self._is_complete = None, None
365 self.code, self._is_complete = None, None
366
366
367 # Honor termination lines properly
367 # Honor termination lines properly
368 if source.rstrip().endswith('\\'):
368 if source.rstrip().endswith('\\'):
369 return False
369 return False
370
370
371 self._update_indent(lines)
371 self._update_indent(lines)
372 try:
372 try:
373 self.code = self._compile(source, symbol="exec")
373 self.code = self._compile(source, symbol="exec")
374 # Invalid syntax can produce any of a number of different errors from
374 # Invalid syntax can produce any of a number of different errors from
375 # inside the compiler, so we have to catch them all. Syntax errors
375 # inside the compiler, so we have to catch them all. Syntax errors
376 # immediately produce a 'ready' block, so the invalid Python can be
376 # immediately produce a 'ready' block, so the invalid Python can be
377 # sent to the kernel for evaluation with possible ipython
377 # sent to the kernel for evaluation with possible ipython
378 # special-syntax conversion.
378 # special-syntax conversion.
379 except (SyntaxError, OverflowError, ValueError, TypeError,
379 except (SyntaxError, OverflowError, ValueError, TypeError,
380 MemoryError):
380 MemoryError):
381 self._is_complete = True
381 self._is_complete = True
382 else:
382 else:
383 # Compilation didn't produce any exceptions (though it may not have
383 # Compilation didn't produce any exceptions (though it may not have
384 # given a complete code object)
384 # given a complete code object)
385 self._is_complete = self.code is not None
385 self._is_complete = self.code is not None
386
386
387 return self._is_complete
387 return self._is_complete
388
388
389 def push_accepts_more(self):
389 def push_accepts_more(self):
390 """Return whether a block of interactive input can accept more input.
390 """Return whether a block of interactive input can accept more input.
391
391
392 This method is meant to be used by line-oriented frontends, who need to
392 This method is meant to be used by line-oriented frontends, who need to
393 guess whether a block is complete or not based solely on prior and
393 guess whether a block is complete or not based solely on prior and
394 current input lines. The InputSplitter considers it has a complete
394 current input lines. The InputSplitter considers it has a complete
395 interactive block and will not accept more input only when either a
395 interactive block and will not accept more input only when either a
396 SyntaxError is raised, or *all* of the following are true:
396 SyntaxError is raised, or *all* of the following are true:
397
397
398 1. The input compiles to a complete statement.
398 1. The input compiles to a complete statement.
399
399
400 2. The indentation level is flush-left (because if we are indented,
400 2. The indentation level is flush-left (because if we are indented,
401 like inside a function definition or for loop, we need to keep
401 like inside a function definition or for loop, we need to keep
402 reading new input).
402 reading new input).
403
403
404 3. There is one extra line consisting only of whitespace.
404 3. There is one extra line consisting only of whitespace.
405
405
406 Because of condition #3, this method should be used only by
406 Because of condition #3, this method should be used only by
407 *line-oriented* frontends, since it means that intermediate blank lines
407 *line-oriented* frontends, since it means that intermediate blank lines
408 are not allowed in function definitions (or any other indented block).
408 are not allowed in function definitions (or any other indented block).
409
409
410 If the current input produces a syntax error, this method immediately
410 If the current input produces a syntax error, this method immediately
411 returns False but does *not* raise the syntax error exception, as
411 returns False but does *not* raise the syntax error exception, as
412 typically clients will want to send invalid syntax to an execution
412 typically clients will want to send invalid syntax to an execution
413 backend which might convert the invalid syntax into valid Python via
413 backend which might convert the invalid syntax into valid Python via
414 one of the dynamic IPython mechanisms.
414 one of the dynamic IPython mechanisms.
415 """
415 """
416
416
417 # With incomplete input, unconditionally accept more
417 # With incomplete input, unconditionally accept more
418 if not self._is_complete:
418 if not self._is_complete:
419 return True
419 return True
420
420
421 # If we already have complete input and we're flush left, the answer
421 # If we already have complete input and we're flush left, the answer
422 # depends. In line mode, if there hasn't been any indentation,
422 # depends. In line mode, if there hasn't been any indentation,
423 # that's it. If we've come back from some indentation, we need
423 # that's it. If we've come back from some indentation, we need
424 # the blank final line to finish.
424 # the blank final line to finish.
425 # In cell mode, we need to check how many blocks the input so far
425 # In cell mode, we need to check how many blocks the input so far
426 # compiles into, because if there's already more than one full
426 # compiles into, because if there's already more than one full
427 # independent block of input, then the client has entered full
427 # independent block of input, then the client has entered full
428 # 'cell' mode and is feeding lines that each is complete. In this
428 # 'cell' mode and is feeding lines that each is complete. In this
429 # case we should then keep accepting. The Qt terminal-like console
429 # case we should then keep accepting. The Qt terminal-like console
430 # does precisely this, to provide the convenience of terminal-like
430 # does precisely this, to provide the convenience of terminal-like
431 # input of single expressions, but allowing the user (with a
431 # input of single expressions, but allowing the user (with a
432 # separate keystroke) to switch to 'cell' mode and type multiple
432 # separate keystroke) to switch to 'cell' mode and type multiple
433 # expressions in one shot.
433 # expressions in one shot.
434 if self.indent_spaces==0:
434 if self.indent_spaces==0:
435 if self.input_mode=='line':
435 if self.input_mode=='line':
436 if not self._full_dedent:
436 if not self._full_dedent:
437 return False
437 return False
438 else:
438 else:
439 try:
439 try:
440 code_ast = ast.parse(u''.join(self._buffer))
440 code_ast = ast.parse(u''.join(self._buffer))
441 except Exception:
441 except Exception:
442 return False
442 return False
443 else:
443 else:
444 if len(code_ast.body) == 1:
444 if len(code_ast.body) == 1:
445 return False
445 return False
446
446
447 # When input is complete, then termination is marked by an extra blank
447 # When input is complete, then termination is marked by an extra blank
448 # line at the end.
448 # line at the end.
449 last_line = self.source.splitlines()[-1]
449 last_line = self.source.splitlines()[-1]
450 return bool(last_line and not last_line.isspace())
450 return bool(last_line and not last_line.isspace())
451
451
452 #------------------------------------------------------------------------
452 #------------------------------------------------------------------------
453 # Private interface
453 # Private interface
454 #------------------------------------------------------------------------
454 #------------------------------------------------------------------------
455
455
456 def _find_indent(self, line):
456 def _find_indent(self, line):
457 """Compute the new indentation level for a single line.
457 """Compute the new indentation level for a single line.
458
458
459 Parameters
459 Parameters
460 ----------
460 ----------
461 line : str
461 line : str
462 A single new line of non-whitespace, non-comment Python input.
462 A single new line of non-whitespace, non-comment Python input.
463
463
464 Returns
464 Returns
465 -------
465 -------
466 indent_spaces : int
466 indent_spaces : int
467 New value for the indent level (it may be equal to self.indent_spaces
467 New value for the indent level (it may be equal to self.indent_spaces
468 if indentation doesn't change.
468 if indentation doesn't change.
469
469
470 full_dedent : boolean
470 full_dedent : boolean
471 Whether the new line causes a full flush-left dedent.
471 Whether the new line causes a full flush-left dedent.
472 """
472 """
473 indent_spaces = self.indent_spaces
473 indent_spaces = self.indent_spaces
474 full_dedent = self._full_dedent
474 full_dedent = self._full_dedent
475
475
476 inisp = num_ini_spaces(line)
476 inisp = num_ini_spaces(line)
477 if inisp < indent_spaces:
477 if inisp < indent_spaces:
478 indent_spaces = inisp
478 indent_spaces = inisp
479 if indent_spaces <= 0:
479 if indent_spaces <= 0:
480 #print 'Full dedent in text',self.source # dbg
480 #print 'Full dedent in text',self.source # dbg
481 full_dedent = True
481 full_dedent = True
482
482
483 if line.rstrip()[-1] == ':':
483 if line.rstrip()[-1] == ':':
484 indent_spaces += 4
484 indent_spaces += 4
485 elif dedent_re.match(line):
485 elif dedent_re.match(line):
486 indent_spaces -= 4
486 indent_spaces -= 4
487 if indent_spaces <= 0:
487 if indent_spaces <= 0:
488 full_dedent = True
488 full_dedent = True
489
489
490 # Safety
490 # Safety
491 if indent_spaces < 0:
491 if indent_spaces < 0:
492 indent_spaces = 0
492 indent_spaces = 0
493 #print 'safety' # dbg
493 #print 'safety' # dbg
494
494
495 return indent_spaces, full_dedent
495 return indent_spaces, full_dedent
496
496
497 def _update_indent(self, lines):
497 def _update_indent(self, lines):
498 for line in remove_comments(lines).splitlines():
498 for line in remove_comments(lines).splitlines():
499 if line and not line.isspace():
499 if line and not line.isspace():
500 self.indent_spaces, self._full_dedent = self._find_indent(line)
500 self.indent_spaces, self._full_dedent = self._find_indent(line)
501
501
502 def _store(self, lines, buffer=None, store='source'):
502 def _store(self, lines, buffer=None, store='source'):
503 """Store one or more lines of input.
503 """Store one or more lines of input.
504
504
505 If input lines are not newline-terminated, a newline is automatically
505 If input lines are not newline-terminated, a newline is automatically
506 appended."""
506 appended."""
507
507
508 if buffer is None:
508 if buffer is None:
509 buffer = self._buffer
509 buffer = self._buffer
510
510
511 if lines.endswith('\n'):
511 if lines.endswith('\n'):
512 buffer.append(lines)
512 buffer.append(lines)
513 else:
513 else:
514 buffer.append(lines+'\n')
514 buffer.append(lines+'\n')
515 setattr(self, store, self._set_source(buffer))
515 setattr(self, store, self._set_source(buffer))
516
516
517 def _set_source(self, buffer):
517 def _set_source(self, buffer):
518 return u''.join(buffer)
518 return u''.join(buffer)
519
519
520
520
521 #-----------------------------------------------------------------------------
521 #-----------------------------------------------------------------------------
522 # Functions and classes for IPython-specific syntactic support
522 # Functions and classes for IPython-specific syntactic support
523 #-----------------------------------------------------------------------------
523 #-----------------------------------------------------------------------------
524
524
525 # The escaped translators ALL receive a line where their own escape has been
525 # The escaped translators ALL receive a line where their own escape has been
526 # stripped. Only '?' is valid at the end of the line, all others can only be
526 # stripped. Only '?' is valid at the end of the line, all others can only be
527 # placed at the start.
527 # placed at the start.
528
528
529 # Transformations of the special syntaxes that don't rely on an explicit escape
529 # Transformations of the special syntaxes that don't rely on an explicit escape
530 # character but instead on patterns on the input line
530 # character but instead on patterns on the input line
531
531
532 # The core transformations are implemented as standalone functions that can be
532 # The core transformations are implemented as standalone functions that can be
533 # tested and validated in isolation. Each of these uses a regexp, we
533 # tested and validated in isolation. Each of these uses a regexp, we
534 # pre-compile these and keep them close to each function definition for clarity
534 # pre-compile these and keep them close to each function definition for clarity
535
535
536 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
536 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
537 r'\s*=\s*!\s*(?P<cmd>.*)')
537 r'\s*=\s*!\s*(?P<cmd>.*)')
538
538
539 def transform_assign_system(line):
539 def transform_assign_system(line):
540 """Handle the `files = !ls` syntax."""
540 """Handle the `files = !ls` syntax."""
541 m = _assign_system_re.match(line)
541 m = _assign_system_re.match(line)
542 if m is not None:
542 if m is not None:
543 cmd = m.group('cmd')
543 cmd = m.group('cmd')
544 lhs = m.group('lhs')
544 lhs = m.group('lhs')
545 new_line = '%s = get_ipython().getoutput(%r)' % (lhs, cmd)
545 new_line = '%s = get_ipython().getoutput(%r)' % (lhs, cmd)
546 return new_line
546 return new_line
547 return line
547 return line
548
548
549
549
550 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
550 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
551 r'\s*=\s*%\s*(?P<cmd>.*)')
551 r'\s*=\s*%\s*(?P<cmd>.*)')
552
552
553 def transform_assign_magic(line):
553 def transform_assign_magic(line):
554 """Handle the `a = %who` syntax."""
554 """Handle the `a = %who` syntax."""
555 m = _assign_magic_re.match(line)
555 m = _assign_magic_re.match(line)
556 if m is not None:
556 if m is not None:
557 cmd = m.group('cmd')
557 cmd = m.group('cmd')
558 lhs = m.group('lhs')
558 lhs = m.group('lhs')
559 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
559 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
560 return new_line
560 return new_line
561 return line
561 return line
562
562
563
563
564 _classic_prompt_re = re.compile(r'^([ \t]*>>> |^[ \t]*\.\.\. )')
564 _classic_prompt_re = re.compile(r'^([ \t]*>>> |^[ \t]*\.\.\. )')
565
565
566 def transform_classic_prompt(line):
566 def transform_classic_prompt(line):
567 """Handle inputs that start with '>>> ' syntax."""
567 """Handle inputs that start with '>>> ' syntax."""
568
568
569 if not line or line.isspace():
569 if not line or line.isspace():
570 return line
570 return line
571 m = _classic_prompt_re.match(line)
571 m = _classic_prompt_re.match(line)
572 if m:
572 if m:
573 return line[len(m.group(0)):]
573 return line[len(m.group(0)):]
574 else:
574 else:
575 return line
575 return line
576
576
577
577
578 _ipy_prompt_re = re.compile(r'^([ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
578 _ipy_prompt_re = re.compile(r'^([ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
579
579
580 def transform_ipy_prompt(line):
580 def transform_ipy_prompt(line):
581 """Handle inputs that start classic IPython prompt syntax."""
581 """Handle inputs that start classic IPython prompt syntax."""
582
582
583 if not line or line.isspace():
583 if not line or line.isspace():
584 return line
584 return line
585 #print 'LINE: %r' % line # dbg
585 #print 'LINE: %r' % line # dbg
586 m = _ipy_prompt_re.match(line)
586 m = _ipy_prompt_re.match(line)
587 if m:
587 if m:
588 #print 'MATCH! %r -> %r' % (line, line[len(m.group(0)):]) # dbg
588 #print 'MATCH! %r -> %r' % (line, line[len(m.group(0)):]) # dbg
589 return line[len(m.group(0)):]
589 return line[len(m.group(0)):]
590 else:
590 else:
591 return line
591 return line
592
592
593
593
594 def _make_help_call(target, esc, lspace, next_input=None):
594 def _make_help_call(target, esc, lspace, next_input=None):
595 """Prepares a pinfo(2)/psearch call from a target name and the escape
595 """Prepares a pinfo(2)/psearch call from a target name and the escape
596 (i.e. ? or ??)"""
596 (i.e. ? or ??)"""
597 method = 'pinfo2' if esc == '??' \
597 method = 'pinfo2' if esc == '??' \
598 else 'psearch' if '*' in target \
598 else 'psearch' if '*' in target \
599 else 'pinfo'
599 else 'pinfo'
600 arg = " ".join([method, target])
600 arg = " ".join([method, target])
601 if next_input is None:
601 if next_input is None:
602 return '%sget_ipython().magic(%r)' % (lspace, arg)
602 return '%sget_ipython().magic(%r)' % (lspace, arg)
603 else:
603 else:
604 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
604 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
605 (lspace, next_input, arg)
605 (lspace, next_input, arg)
606
606
607
607
608 _initial_space_re = re.compile(r'\s*')
608 _initial_space_re = re.compile(r'\s*')
609
609
610 _help_end_re = re.compile(r"""(%{0,2}
610 _help_end_re = re.compile(r"""(%{0,2}
611 [a-zA-Z_*][\w*]* # Variable name
611 [a-zA-Z_*][\w*]* # Variable name
612 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
612 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
613 )
613 )
614 (\?\??)$ # ? or ??""",
614 (\?\??)$ # ? or ??""",
615 re.VERBOSE)
615 re.VERBOSE)
616
616
617
617
618 def transform_help_end(line):
618 def transform_help_end(line):
619 """Translate lines with ?/?? at the end"""
619 """Translate lines with ?/?? at the end"""
620 m = _help_end_re.search(line)
620 m = _help_end_re.search(line)
621 if m is None or has_comment(line):
621 if m is None or has_comment(line):
622 return line
622 return line
623 target = m.group(1)
623 target = m.group(1)
624 esc = m.group(3)
624 esc = m.group(3)
625 lspace = _initial_space_re.match(line).group(0)
625 lspace = _initial_space_re.match(line).group(0)
626
626
627 # If we're mid-command, put it back on the next prompt for the user.
627 # If we're mid-command, put it back on the next prompt for the user.
628 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
628 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
629
629
630 return _make_help_call(target, esc, lspace, next_input)
630 return _make_help_call(target, esc, lspace, next_input)
631
631
632
632
633 class EscapedTransformer(object):
633 class EscapedTransformer(object):
634 """Class to transform lines that are explicitly escaped out."""
634 """Class to transform lines that are explicitly escaped out."""
635
635
636 def __init__(self):
636 def __init__(self):
637 tr = { ESC_SHELL : self._tr_system,
637 tr = { ESC_SHELL : self._tr_system,
638 ESC_SH_CAP : self._tr_system2,
638 ESC_SH_CAP : self._tr_system2,
639 ESC_HELP : self._tr_help,
639 ESC_HELP : self._tr_help,
640 ESC_HELP2 : self._tr_help,
640 ESC_HELP2 : self._tr_help,
641 ESC_MAGIC : self._tr_magic,
641 ESC_MAGIC : self._tr_magic,
642 ESC_QUOTE : self._tr_quote,
642 ESC_QUOTE : self._tr_quote,
643 ESC_QUOTE2 : self._tr_quote2,
643 ESC_QUOTE2 : self._tr_quote2,
644 ESC_PAREN : self._tr_paren }
644 ESC_PAREN : self._tr_paren }
645 self.tr = tr
645 self.tr = tr
646
646
647 # Support for syntax transformations that use explicit escapes typed by the
647 # Support for syntax transformations that use explicit escapes typed by the
648 # user at the beginning of a line
648 # user at the beginning of a line
649 @staticmethod
649 @staticmethod
650 def _tr_system(line_info):
650 def _tr_system(line_info):
651 "Translate lines escaped with: !"
651 "Translate lines escaped with: !"
652 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
652 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
653 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
653 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
654
654
655 @staticmethod
655 @staticmethod
656 def _tr_system2(line_info):
656 def _tr_system2(line_info):
657 "Translate lines escaped with: !!"
657 "Translate lines escaped with: !!"
658 cmd = line_info.line.lstrip()[2:]
658 cmd = line_info.line.lstrip()[2:]
659 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
659 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
660
660
661 @staticmethod
661 @staticmethod
662 def _tr_help(line_info):
662 def _tr_help(line_info):
663 "Translate lines escaped with: ?/??"
663 "Translate lines escaped with: ?/??"
664 # A naked help line should just fire the intro help screen
664 # A naked help line should just fire the intro help screen
665 if not line_info.line[1:]:
665 if not line_info.line[1:]:
666 return 'get_ipython().show_usage()'
666 return 'get_ipython().show_usage()'
667
667
668 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
668 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
669
669
670 @staticmethod
670 @staticmethod
671 def _tr_magic(line_info):
671 def _tr_magic(line_info):
672 "Translate lines escaped with: %"
672 "Translate lines escaped with: %"
673 tpl = '%sget_ipython().magic(%r)'
673 tpl = '%sget_ipython().magic(%r)'
674 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
674 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
675 return tpl % (line_info.pre, cmd)
675 return tpl % (line_info.pre, cmd)
676
676
677 @staticmethod
677 @staticmethod
678 def _tr_quote(line_info):
678 def _tr_quote(line_info):
679 "Translate lines escaped with: ,"
679 "Translate lines escaped with: ,"
680 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
680 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
681 '", "'.join(line_info.the_rest.split()) )
681 '", "'.join(line_info.the_rest.split()) )
682
682
683 @staticmethod
683 @staticmethod
684 def _tr_quote2(line_info):
684 def _tr_quote2(line_info):
685 "Translate lines escaped with: ;"
685 "Translate lines escaped with: ;"
686 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
686 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
687 line_info.the_rest)
687 line_info.the_rest)
688
688
689 @staticmethod
689 @staticmethod
690 def _tr_paren(line_info):
690 def _tr_paren(line_info):
691 "Translate lines escaped with: /"
691 "Translate lines escaped with: /"
692 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
692 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
693 ", ".join(line_info.the_rest.split()))
693 ", ".join(line_info.the_rest.split()))
694
694
695 def __call__(self, line):
695 def __call__(self, line):
696 """Class to transform lines that are explicitly escaped out.
696 """Class to transform lines that are explicitly escaped out.
697
697
698 This calls the above _tr_* static methods for the actual line
698 This calls the above _tr_* static methods for the actual line
699 translations."""
699 translations."""
700
700
701 # Empty lines just get returned unmodified
701 # Empty lines just get returned unmodified
702 if not line or line.isspace():
702 if not line or line.isspace():
703 return line
703 return line
704
704
705 # Get line endpoints, where the escapes can be
705 # Get line endpoints, where the escapes can be
706 line_info = LineInfo(line)
706 line_info = LineInfo(line)
707
707
708 if not line_info.esc in self.tr:
708 if not line_info.esc in self.tr:
709 # If we don't recognize the escape, don't modify the line
709 # If we don't recognize the escape, don't modify the line
710 return line
710 return line
711
711
712 return self.tr[line_info.esc](line_info)
712 return self.tr[line_info.esc](line_info)
713
713
714
714
715 # A function-looking object to be used by the rest of the code. The purpose of
715 # A function-looking object to be used by the rest of the code. The purpose of
716 # the class in this case is to organize related functionality, more than to
716 # the class in this case is to organize related functionality, more than to
717 # manage state.
717 # manage state.
718 transform_escaped = EscapedTransformer()
718 transform_escaped = EscapedTransformer()
719
719
720
720
721 class IPythonInputSplitter(InputSplitter):
721 class IPythonInputSplitter(InputSplitter):
722 """An input splitter that recognizes all of IPython's special syntax."""
722 """An input splitter that recognizes all of IPython's special syntax."""
723
723
724 # String with raw, untransformed input.
724 # String with raw, untransformed input.
725 source_raw = ''
725 source_raw = ''
726
726
727 # Flag to track when we're in the middle of processing a cell magic, since
727 # Flag to track when we're in the middle of processing a cell magic, since
728 # the logic has to change. In that case, we apply no transformations at
728 # the logic has to change. In that case, we apply no transformations at
729 # all.
729 # all.
730 processing_cell_magic = False
730 processing_cell_magic = False
731
731
732 # Storage for all blocks of input that make up a cell magic
732 # Storage for all blocks of input that make up a cell magic
733 cell_magic_parts = []
733 cell_magic_parts = []
734
734
735 # Private attributes
735 # Private attributes
736
736
737 # List with lines of raw input accumulated so far.
737 # List with lines of raw input accumulated so far.
738 _buffer_raw = None
738 _buffer_raw = None
739
739
740 def __init__(self, input_mode=None):
740 def __init__(self, input_mode=None):
741 super(IPythonInputSplitter, self).__init__(input_mode)
741 super(IPythonInputSplitter, self).__init__(input_mode)
742 self._buffer_raw = []
742 self._buffer_raw = []
743 self._validate = True
743 self._validate = True
744
744
745 def reset(self):
745 def reset(self):
746 """Reset the input buffer and associated state."""
746 """Reset the input buffer and associated state."""
747 super(IPythonInputSplitter, self).reset()
747 super(IPythonInputSplitter, self).reset()
748 self._buffer_raw[:] = []
748 self._buffer_raw[:] = []
749 self.source_raw = ''
749 self.source_raw = ''
750 self.cell_magic_parts = []
750 self.cell_magic_parts = []
751 self.processing_cell_magic = False
751 self.processing_cell_magic = False
752
752
753 def source_raw_reset(self):
753 def source_raw_reset(self):
754 """Return input and raw source and perform a full reset.
754 """Return input and raw source and perform a full reset.
755 """
755 """
756 out = self.source
756 out = self.source
757 out_r = self.source_raw
757 out_r = self.source_raw
758 self.reset()
758 self.reset()
759 return out, out_r
759 return out, out_r
760
760
761 def push_accepts_more(self):
761 def push_accepts_more(self):
762 if self.processing_cell_magic:
762 if self.processing_cell_magic:
763 return not self._is_complete
763 return not self._is_complete
764 else:
764 else:
765 return super(IPythonInputSplitter, self).push_accepts_more()
765 return super(IPythonInputSplitter, self).push_accepts_more()
766
766
767 def _handle_cell_magic(self, lines):
767 def _handle_cell_magic(self, lines):
768 """Process lines when they start with %%, which marks cell magics.
768 """Process lines when they start with %%, which marks cell magics.
769 """
769 """
770 self.processing_cell_magic = True
770 self.processing_cell_magic = True
771 first, _, body = lines.partition('\n')
771 first, _, body = lines.partition('\n')
772 magic_name, _, line = first.partition(' ')
772 magic_name, _, line = first.partition(' ')
773 magic_name = magic_name.lstrip(ESC_MAGIC)
773 magic_name = magic_name.lstrip(ESC_MAGIC)
774 # We store the body of the cell and create a call to a method that
774 # We store the body of the cell and create a call to a method that
775 # will use this stored value. This is ugly, but it's a first cut to
775 # will use this stored value. This is ugly, but it's a first cut to
776 # get it all working, as right now changing the return API of our
776 # get it all working, as right now changing the return API of our
777 # methods would require major refactoring.
777 # methods would require major refactoring.
778 self.cell_magic_parts = [body]
778 self.cell_magic_parts = [body]
779 tpl = 'get_ipython()._run_cached_cell_magic(%r, %r)'
779 tpl = 'get_ipython()._run_cached_cell_magic(%r, %r)'
780 tlines = tpl % (magic_name, line)
780 tlines = tpl % (magic_name, line)
781 self._store(tlines)
781 self._store(tlines)
782 self._store(lines, self._buffer_raw, 'source_raw')
782 self._store(lines, self._buffer_raw, 'source_raw')
783 # We can actually choose whether to allow for single blank lines here
783 # We can actually choose whether to allow for single blank lines here
784 # during input for clients that use cell mode to decide when to stop
784 # during input for clients that use cell mode to decide when to stop
785 # pushing input (currently only the Qt console).
785 # pushing input (currently only the Qt console).
786 # My first implementation did that, and then I realized it wasn't
786 # My first implementation did that, and then I realized it wasn't
787 # consistent with the terminal behavior, so I've reverted it to one
787 # consistent with the terminal behavior, so I've reverted it to one
788 # line. But I'm leaving it here so we can easily test both behaviors,
788 # line. But I'm leaving it here so we can easily test both behaviors,
789 # I kind of liked having full blank lines allowed in the cell magics...
789 # I kind of liked having full blank lines allowed in the cell magics...
790 #self._is_complete = last_two_blanks(lines)
790 #self._is_complete = last_two_blanks(lines)
791 self._is_complete = last_blank(lines)
791 self._is_complete = last_blank(lines)
792 return self._is_complete
792 return self._is_complete
793
793
794 def _line_mode_cell_append(self, lines):
794 def _line_mode_cell_append(self, lines):
795 """Append new content for a cell magic in line mode.
795 """Append new content for a cell magic in line mode.
796 """
796 """
797 # Only store the raw input. Lines beyond the first one are only only
797 # Only store the raw input. Lines beyond the first one are only only
798 # stored for history purposes; for execution the caller will grab the
798 # stored for history purposes; for execution the caller will grab the
799 # magic pieces from cell_magic_parts and will assemble the cell body
799 # magic pieces from cell_magic_parts and will assemble the cell body
800 self._store(lines, self._buffer_raw, 'source_raw')
800 self._store(lines, self._buffer_raw, 'source_raw')
801 self.cell_magic_parts.append(lines)
801 self.cell_magic_parts.append(lines)
802 # Find out if the last stored block has a whitespace line as its
802 # Find out if the last stored block has a whitespace line as its
803 # last line and also this line is whitespace, case in which we're
803 # last line and also this line is whitespace, case in which we're
804 # done (two contiguous blank lines signal termination). Note that
804 # done (two contiguous blank lines signal termination). Note that
805 # the storage logic *enforces* that every stored block is
805 # the storage logic *enforces* that every stored block is
806 # newline-terminated, so we grab everything but the last character
806 # newline-terminated, so we grab everything but the last character
807 # so we can have the body of the block alone.
807 # so we can have the body of the block alone.
808 last_block = self.cell_magic_parts[-1]
808 last_block = self.cell_magic_parts[-1]
809 self._is_complete = last_blank(last_block) and lines.isspace()
809 self._is_complete = last_blank(last_block) and lines.isspace()
810 return self._is_complete
810 return self._is_complete
811
811
812 def transform_cell(self, cell):
813 """Process and translate a cell of input.
814 """
815 self.reset()
816 self.push(cell)
817 return self.source_reset()
818
812 def push(self, lines):
819 def push(self, lines):
813 """Push one or more lines of IPython input.
820 """Push one or more lines of IPython input.
814
821
815 This stores the given lines and returns a status code indicating
822 This stores the given lines and returns a status code indicating
816 whether the code forms a complete Python block or not, after processing
823 whether the code forms a complete Python block or not, after processing
817 all input lines for special IPython syntax.
824 all input lines for special IPython syntax.
818
825
819 Any exceptions generated in compilation are swallowed, but if an
826 Any exceptions generated in compilation are swallowed, but if an
820 exception was produced, the method returns True.
827 exception was produced, the method returns True.
821
828
822 Parameters
829 Parameters
823 ----------
830 ----------
824 lines : string
831 lines : string
825 One or more lines of Python input.
832 One or more lines of Python input.
826
833
827 Returns
834 Returns
828 -------
835 -------
829 is_complete : boolean
836 is_complete : boolean
830 True if the current input source (the result of the current input
837 True if the current input source (the result of the current input
831 plus prior inputs) forms a complete Python execution block. Note that
838 plus prior inputs) forms a complete Python execution block. Note that
832 this value is also stored as a private attribute (_is_complete), so it
839 this value is also stored as a private attribute (_is_complete), so it
833 can be queried at any time.
840 can be queried at any time.
834 """
841 """
835 if not lines:
842 if not lines:
836 return super(IPythonInputSplitter, self).push(lines)
843 return super(IPythonInputSplitter, self).push(lines)
837
844
838 # We must ensure all input is pure unicode
845 # We must ensure all input is pure unicode
839 lines = cast_unicode(lines, self.encoding)
846 lines = cast_unicode(lines, self.encoding)
840
847
841 # If the entire input block is a cell magic, return after handling it
848 # If the entire input block is a cell magic, return after handling it
842 # as the rest of the transformation logic should be skipped.
849 # as the rest of the transformation logic should be skipped.
843 if lines.startswith('%%') and not \
850 if lines.startswith('%%') and not \
844 (len(lines.splitlines()) == 1 and lines.strip().endswith('?')):
851 (len(lines.splitlines()) == 1 and lines.strip().endswith('?')):
845 return self._handle_cell_magic(lines)
852 return self._handle_cell_magic(lines)
846
853
847 # In line mode, a cell magic can arrive in separate pieces
854 # In line mode, a cell magic can arrive in separate pieces
848 if self.input_mode == 'line' and self.processing_cell_magic:
855 if self.input_mode == 'line' and self.processing_cell_magic:
849 return self._line_mode_cell_append(lines)
856 return self._line_mode_cell_append(lines)
850
857
851 # The rest of the processing is for 'normal' content, i.e. IPython
858 # The rest of the processing is for 'normal' content, i.e. IPython
852 # source that we process through our transformations pipeline.
859 # source that we process through our transformations pipeline.
853 lines_list = lines.splitlines()
860 lines_list = lines.splitlines()
854
861
855 transforms = [transform_ipy_prompt, transform_classic_prompt,
862 transforms = [transform_ipy_prompt, transform_classic_prompt,
856 transform_help_end, transform_escaped,
863 transform_help_end, transform_escaped,
857 transform_assign_system, transform_assign_magic]
864 transform_assign_system, transform_assign_magic]
858
865
859 # Transform logic
866 # Transform logic
860 #
867 #
861 # We only apply the line transformers to the input if we have either no
868 # We only apply the line transformers to the input if we have either no
862 # input yet, or complete input, or if the last line of the buffer ends
869 # input yet, or complete input, or if the last line of the buffer ends
863 # with ':' (opening an indented block). This prevents the accidental
870 # with ':' (opening an indented block). This prevents the accidental
864 # transformation of escapes inside multiline expressions like
871 # transformation of escapes inside multiline expressions like
865 # triple-quoted strings or parenthesized expressions.
872 # triple-quoted strings or parenthesized expressions.
866 #
873 #
867 # The last heuristic, while ugly, ensures that the first line of an
874 # The last heuristic, while ugly, ensures that the first line of an
868 # indented block is correctly transformed.
875 # indented block is correctly transformed.
869 #
876 #
870 # FIXME: try to find a cleaner approach for this last bit.
877 # FIXME: try to find a cleaner approach for this last bit.
871
878
872 # If we were in 'block' mode, since we're going to pump the parent
879 # If we were in 'block' mode, since we're going to pump the parent
873 # class by hand line by line, we need to temporarily switch out to
880 # class by hand line by line, we need to temporarily switch out to
874 # 'line' mode, do a single manual reset and then feed the lines one
881 # 'line' mode, do a single manual reset and then feed the lines one
875 # by one. Note that this only matters if the input has more than one
882 # by one. Note that this only matters if the input has more than one
876 # line.
883 # line.
877 changed_input_mode = False
884 changed_input_mode = False
878
885
879 if self.input_mode == 'cell':
886 if self.input_mode == 'cell':
880 self.reset()
887 self.reset()
881 changed_input_mode = True
888 changed_input_mode = True
882 saved_input_mode = 'cell'
889 saved_input_mode = 'cell'
883 self.input_mode = 'line'
890 self.input_mode = 'line'
884
891
885 # Store raw source before applying any transformations to it. Note
892 # Store raw source before applying any transformations to it. Note
886 # that this must be done *after* the reset() call that would otherwise
893 # that this must be done *after* the reset() call that would otherwise
887 # flush the buffer.
894 # flush the buffer.
888 self._store(lines, self._buffer_raw, 'source_raw')
895 self._store(lines, self._buffer_raw, 'source_raw')
889
896
890 try:
897 try:
891 push = super(IPythonInputSplitter, self).push
898 push = super(IPythonInputSplitter, self).push
892 buf = self._buffer
899 buf = self._buffer
893 for line in lines_list:
900 for line in lines_list:
894 if self._is_complete or not buf or \
901 if self._is_complete or not buf or \
895 (buf and buf[-1].rstrip().endswith((':', ','))):
902 (buf and buf[-1].rstrip().endswith((':', ','))):
896 for f in transforms:
903 for f in transforms:
897 line = f(line)
904 line = f(line)
898
905
899 out = push(line)
906 out = push(line)
900 finally:
907 finally:
901 if changed_input_mode:
908 if changed_input_mode:
902 self.input_mode = saved_input_mode
909 self.input_mode = saved_input_mode
903 return out
910 return out
General Comments 0
You need to be logged in to leave comments. Login now