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