Show More
@@ -247,8 +247,6 b' class InputSplitter(object):' | |||
|
247 | 247 | # synced to the source, so it can be queried at any time to obtain the code |
|
248 | 248 | # object; it will be None if the source doesn't compile to valid Python. |
|
249 | 249 | code = None |
|
250 | # Input mode | |
|
251 | input_mode = 'line' | |
|
252 | 250 | |
|
253 | 251 | # Private attributes |
|
254 | 252 | |
@@ -261,32 +259,12 b' class InputSplitter(object):' | |||
|
261 | 259 | # Boolean indicating whether the current block is complete |
|
262 | 260 | _is_complete = None |
|
263 | 261 | |
|
264 |
def __init__(self |
|
|
262 | def __init__(self): | |
|
265 | 263 | """Create a new InputSplitter instance. |
|
266 | ||
|
267 | Parameters | |
|
268 | ---------- | |
|
269 | input_mode : str | |
|
270 | ||
|
271 | One of ['line', 'cell']; default is 'line'. | |
|
272 | ||
|
273 | The input_mode parameter controls how new inputs are used when fed via | |
|
274 | the :meth:`push` method: | |
|
275 | ||
|
276 | - 'line': meant for line-oriented clients, inputs are appended one at a | |
|
277 | time to the internal buffer and the whole buffer is compiled. | |
|
278 | ||
|
279 | - 'cell': meant for clients that can edit multi-line 'cells' of text at | |
|
280 | a time. A cell can contain one or more blocks that can be compile in | |
|
281 | 'single' mode by Python. In this mode, each new input new input | |
|
282 | completely replaces all prior inputs. Cell mode is thus equivalent | |
|
283 | to prepending a full reset() to every push() call. | |
|
284 | 264 | """ |
|
285 | 265 | self._buffer = [] |
|
286 | 266 | self._compile = codeop.CommandCompiler() |
|
287 | 267 | self.encoding = get_input_encoding() |
|
288 | self.input_mode = InputSplitter.input_mode if input_mode is None \ | |
|
289 | else input_mode | |
|
290 | 268 | |
|
291 | 269 | def reset(self): |
|
292 | 270 | """Reset the input buffer and associated state.""" |
@@ -326,9 +304,6 b' class InputSplitter(object):' | |||
|
326 | 304 | this value is also stored as a private attribute (``_is_complete``), so it |
|
327 | 305 | can be queried at any time. |
|
328 | 306 | """ |
|
329 | if self.input_mode == 'cell': | |
|
330 | self.reset() | |
|
331 | ||
|
332 | 307 | self._store(lines) |
|
333 | 308 | source = self.source |
|
334 | 309 | |
@@ -365,20 +340,14 b' class InputSplitter(object):' | |||
|
365 | 340 | This method is meant to be used by line-oriented frontends, who need to |
|
366 | 341 | guess whether a block is complete or not based solely on prior and |
|
367 | 342 | current input lines. The InputSplitter considers it has a complete |
|
368 |
interactive block and will not accept more input |
|
|
369 | SyntaxError is raised, or *all* of the following are true: | |
|
370 | ||
|
371 | 1. The input compiles to a complete statement. | |
|
372 | ||
|
373 | 2. The indentation level is flush-left (because if we are indented, | |
|
374 | like inside a function definition or for loop, we need to keep | |
|
375 | reading new input). | |
|
343 | interactive block and will not accept more input when either: | |
|
344 | ||
|
345 | * A SyntaxError is raised | |
|
376 | 346 | |
|
377 | 3. There is one extra line consisting only of whitespace. | |
|
347 | * The code is complete and consists of a single line or a single | |
|
348 | non-compound statement | |
|
378 | 349 | |
|
379 | Because of condition #3, this method should be used only by | |
|
380 | *line-oriented* frontends, since it means that intermediate blank lines | |
|
381 | are not allowed in function definitions (or any other indented block). | |
|
350 | * The code is complete and has a blank line at the end | |
|
382 | 351 | |
|
383 | 352 | If the current input produces a syntax error, this method immediately |
|
384 | 353 | returns False but does *not* raise the syntax error exception, as |
@@ -388,39 +357,37 b' class InputSplitter(object):' | |||
|
388 | 357 | """ |
|
389 | 358 | |
|
390 | 359 | # With incomplete input, unconditionally accept more |
|
360 | # A syntax error also sets _is_complete to True - see push() | |
|
391 | 361 | if not self._is_complete: |
|
362 | #print("Not complete") # debug | |
|
392 | 363 | return True |
|
393 | ||
|
394 | # If we already have complete input and we're flush left, the answer | |
|
395 | # depends. In line mode, if there hasn't been any indentation, | |
|
396 | # that's it. If we've come back from some indentation, we need | |
|
397 | # the blank final line to finish. | |
|
398 | # In cell mode, we need to check how many blocks the input so far | |
|
399 | # compiles into, because if there's already more than one full | |
|
400 | # independent block of input, then the client has entered full | |
|
401 | # 'cell' mode and is feeding lines that each is complete. In this | |
|
402 | # case we should then keep accepting. The Qt terminal-like console | |
|
403 | # does precisely this, to provide the convenience of terminal-like | |
|
404 | # input of single expressions, but allowing the user (with a | |
|
405 | # separate keystroke) to switch to 'cell' mode and type multiple | |
|
406 | # expressions in one shot. | |
|
364 | ||
|
365 | # The user can make any (complete) input execute by leaving a blank line | |
|
366 | last_line = self.source.splitlines()[-1] | |
|
367 | if (not last_line) or last_line.isspace(): | |
|
368 | #print("Blank line") # debug | |
|
369 | return False | |
|
370 | ||
|
371 | # If there's just a single line or AST node, and we're flush left, as is | |
|
372 | # the case after a simple statement such as 'a=1', we want to execute it | |
|
373 | # straight away. | |
|
407 | 374 | if self.indent_spaces==0: |
|
408 |
if self. |
|
|
409 | if not self._full_dedent: | |
|
410 | return False | |
|
375 | if len(self.source.splitlines()) <= 1: | |
|
376 | return False | |
|
377 | ||
|
378 | try: | |
|
379 | code_ast = ast.parse(u''.join(self._buffer)) | |
|
380 | except Exception: | |
|
381 | #print("Can't parse AST") # debug | |
|
382 | return False | |
|
411 | 383 | else: |
|
412 | try: | |
|
413 | code_ast = ast.parse(u''.join(self._buffer)) | |
|
414 | except Exception: | |
|
384 | if len(code_ast.body) == 1 and \ | |
|
385 | not hasattr(code_ast.body[0], 'body'): | |
|
386 | #print("Simple statement") # debug | |
|
415 | 387 | return False |
|
416 | else: | |
|
417 | if len(code_ast.body) == 1: | |
|
418 | return False | |
|
419 | 388 | |
|
420 | # When input is complete, then termination is marked by an extra blank | |
|
421 | # line at the end. | |
|
422 | last_line = self.source.splitlines()[-1] | |
|
423 | return bool(last_line and not last_line.isspace()) | |
|
389 | # General fallback - accept more code | |
|
390 | return True | |
|
424 | 391 | |
|
425 | 392 | #------------------------------------------------------------------------ |
|
426 | 393 | # Private interface |
@@ -510,9 +477,9 b' class IPythonInputSplitter(InputSplitter):' | |||
|
510 | 477 | # List with lines of raw input accumulated so far. |
|
511 | 478 | _buffer_raw = None |
|
512 | 479 | |
|
513 |
def __init__(self, input_ |
|
|
480 | def __init__(self, line_input_checker=False, physical_line_transforms=None, | |
|
514 | 481 | logical_line_transforms=None, python_line_transforms=None): |
|
515 |
super(IPythonInputSplitter, self).__init__( |
|
|
482 | super(IPythonInputSplitter, self).__init__() | |
|
516 | 483 | self._buffer_raw = [] |
|
517 | 484 | self._validate = True |
|
518 | 485 | |
@@ -528,7 +495,7 b' class IPythonInputSplitter(InputSplitter):' | |||
|
528 | 495 | if logical_line_transforms is not None: |
|
529 | 496 | self.logical_line_transforms = logical_line_transforms |
|
530 | 497 | else: |
|
531 | self.logical_line_transforms = [cellmagic(), | |
|
498 | self.logical_line_transforms = [cellmagic(end_on_blank_line=line_input_checker), | |
|
532 | 499 | help_end(), |
|
533 | 500 | escaped_commands(), |
|
534 | 501 | assign_from_magic(), |
@@ -641,44 +608,14 b' class IPythonInputSplitter(InputSplitter):' | |||
|
641 | 608 | if not lines_list: |
|
642 | 609 | lines_list = [''] |
|
643 | 610 | |
|
644 | # Transform logic | |
|
645 | # | |
|
646 | # We only apply the line transformers to the input if we have either no | |
|
647 | # input yet, or complete input, or if the last line of the buffer ends | |
|
648 | # with ':' (opening an indented block). This prevents the accidental | |
|
649 | # transformation of escapes inside multiline expressions like | |
|
650 | # triple-quoted strings or parenthesized expressions. | |
|
651 | # | |
|
652 | # The last heuristic, while ugly, ensures that the first line of an | |
|
653 | # indented block is correctly transformed. | |
|
654 | # | |
|
655 | # FIXME: try to find a cleaner approach for this last bit. | |
|
656 | ||
|
657 | # If we were in 'block' mode, since we're going to pump the parent | |
|
658 | # class by hand line by line, we need to temporarily switch out to | |
|
659 | # 'line' mode, do a single manual reset and then feed the lines one | |
|
660 | # by one. Note that this only matters if the input has more than one | |
|
661 | # line. | |
|
662 | changed_input_mode = False | |
|
663 | ||
|
664 | if self.input_mode == 'cell': | |
|
665 | self.reset() | |
|
666 | changed_input_mode = True | |
|
667 | saved_input_mode = 'cell' | |
|
668 | self.input_mode = 'line' | |
|
669 | ||
|
670 | 611 | # Store raw source before applying any transformations to it. Note |
|
671 | 612 | # that this must be done *after* the reset() call that would otherwise |
|
672 | 613 | # flush the buffer. |
|
673 | 614 | self._store(lines, self._buffer_raw, 'source_raw') |
|
674 | 615 | |
|
675 | try: | |
|
676 | for line in lines_list: | |
|
677 | out = self.push_line(line) | |
|
678 | finally: | |
|
679 | if changed_input_mode: | |
|
680 | self.input_mode = saved_input_mode | |
|
681 | ||
|
616 | for line in lines_list: | |
|
617 | out = self.push_line(line) | |
|
618 | ||
|
682 | 619 | return out |
|
683 | 620 | |
|
684 | 621 | def push_line(self, line): |
@@ -60,8 +60,8 b' class InputTransformer(object):' | |||
|
60 | 60 | will allow instantiation with the decorated object. |
|
61 | 61 | """ |
|
62 | 62 | @functools.wraps(func) |
|
63 | def transformer_factory(): | |
|
64 | return cls(func) | |
|
63 | def transformer_factory(**kwargs): | |
|
64 | return cls(func, **kwargs) | |
|
65 | 65 | |
|
66 | 66 | return transformer_factory |
|
67 | 67 | |
@@ -84,9 +84,9 b' class StatelessInputTransformer(InputTransformer):' | |||
|
84 | 84 | |
|
85 | 85 | class CoroutineInputTransformer(InputTransformer): |
|
86 | 86 | """Wrapper for an input transformer implemented as a coroutine.""" |
|
87 | def __init__(self, coro): | |
|
87 | def __init__(self, coro, **kwargs): | |
|
88 | 88 | # Prime it |
|
89 | self.coro = coro() | |
|
89 | self.coro = coro(**kwargs) | |
|
90 | 90 | next(self.coro) |
|
91 | 91 | |
|
92 | 92 | def __repr__(self): |
@@ -316,7 +316,7 b' def help_end(line):' | |||
|
316 | 316 | |
|
317 | 317 | |
|
318 | 318 | @CoroutineInputTransformer.wrap |
|
319 | def cellmagic(): | |
|
319 | def cellmagic(end_on_blank_line=False): | |
|
320 | 320 | """Captures & transforms cell magics. |
|
321 | 321 | |
|
322 | 322 | After a cell magic is started, this stores up any lines it gets until it is |
@@ -337,7 +337,8 b' def cellmagic():' | |||
|
337 | 337 | first = line |
|
338 | 338 | body = [] |
|
339 | 339 | line = (yield None) |
|
340 |
while (line is not None) and |
|
|
340 | while (line is not None) and \ | |
|
341 | ((line.strip() != '') or not end_on_blank_line): | |
|
341 | 342 | body.append(line) |
|
342 | 343 | line = (yield None) |
|
343 | 344 |
@@ -283,10 +283,16 b' class InteractiveShell(SingletonConfigurable):' | |||
|
283 | 283 | filename = Unicode("<ipython console>") |
|
284 | 284 | ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__ |
|
285 | 285 | |
|
286 | # Input splitter, to split entire cells of input into either individual | |
|
287 | # interactive statements or whole blocks. | |
|
286 | # Input splitter, to transform input line by line and detect when a block | |
|
287 | # is ready to be executed. | |
|
288 | 288 | input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter', |
|
289 | (), {}) | |
|
289 | (), {'line_input_checker': True}) | |
|
290 | ||
|
291 | # This InputSplitter instance is used to transform completed cells before | |
|
292 | # running them. It allows cell magics to contain blank lines. | |
|
293 | input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter', | |
|
294 | (), {'line_input_checker': False}) | |
|
295 | ||
|
290 | 296 | logstart = CBool(False, config=True, help= |
|
291 | 297 | """ |
|
292 | 298 | Start logging to the default log file. |
@@ -2581,10 +2587,9 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2581 | 2587 | if silent: |
|
2582 | 2588 | store_history = False |
|
2583 | 2589 | |
|
2584 |
self.input_ |
|
|
2590 | self.input_transformer_manager.push(raw_cell) | |
|
2591 | cell = self.input_transformer_manager.source_reset() | |
|
2585 | 2592 | |
|
2586 | cell = self.input_splitter.source_reset() | |
|
2587 | ||
|
2588 | 2593 | # Our own compiler remembers the __future__ environment. If we want to |
|
2589 | 2594 | # run code with a separate __future__ environment, use the default |
|
2590 | 2595 | # compiler |
@@ -168,9 +168,6 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
168 | 168 | self.assertEqual(isp.indent_spaces, 0) |
|
169 | 169 | |
|
170 | 170 | def test_indent2(self): |
|
171 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
172 | if self.isp.input_mode == 'cell': return | |
|
173 | ||
|
174 | 171 | isp = self.isp |
|
175 | 172 | isp.push('if 1:') |
|
176 | 173 | self.assertEqual(isp.indent_spaces, 4) |
@@ -181,9 +178,6 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
181 | 178 | self.assertEqual(isp.indent_spaces, 4) |
|
182 | 179 | |
|
183 | 180 | def test_indent3(self): |
|
184 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
185 | if self.isp.input_mode == 'cell': return | |
|
186 | ||
|
187 | 181 | isp = self.isp |
|
188 | 182 | # When a multiline statement contains parens or multiline strings, we |
|
189 | 183 | # shouldn't get confused. |
@@ -192,9 +186,6 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
192 | 186 | self.assertEqual(isp.indent_spaces, 4) |
|
193 | 187 | |
|
194 | 188 | def test_indent4(self): |
|
195 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
196 | if self.isp.input_mode == 'cell': return | |
|
197 | ||
|
198 | 189 | isp = self.isp |
|
199 | 190 | # whitespace after ':' should not screw up indent level |
|
200 | 191 | isp.push('if 1: \n x=1') |
@@ -279,23 +270,12 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
279 | 270 | isp.push(' a = 1') |
|
280 | 271 | self.assertFalse(isp.push('b = [1,')) |
|
281 | 272 | |
|
282 | def test_replace_mode(self): | |
|
283 | isp = self.isp | |
|
284 | isp.input_mode = 'cell' | |
|
285 | isp.push('x=1') | |
|
286 | self.assertEqual(isp.source, 'x=1\n') | |
|
287 | isp.push('x=2') | |
|
288 | self.assertEqual(isp.source, 'x=2\n') | |
|
289 | ||
|
290 | 273 | def test_push_accepts_more(self): |
|
291 | 274 | isp = self.isp |
|
292 | 275 | isp.push('x=1') |
|
293 | 276 | self.assertFalse(isp.push_accepts_more()) |
|
294 | 277 | |
|
295 | 278 | def test_push_accepts_more2(self): |
|
296 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
297 | if self.isp.input_mode == 'cell': return | |
|
298 | ||
|
299 | 279 | isp = self.isp |
|
300 | 280 | isp.push('if 1:') |
|
301 | 281 | self.assertTrue(isp.push_accepts_more()) |
@@ -310,9 +290,6 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
310 | 290 | self.assertFalse(isp.push_accepts_more()) |
|
311 | 291 | |
|
312 | 292 | def test_push_accepts_more4(self): |
|
313 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
314 | if self.isp.input_mode == 'cell': return | |
|
315 | ||
|
316 | 293 | isp = self.isp |
|
317 | 294 | # When a multiline statement contains parens or multiline strings, we |
|
318 | 295 | # shouldn't get confused. |
@@ -331,14 +308,13 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
331 | 308 | self.assertFalse(isp.push_accepts_more()) |
|
332 | 309 | |
|
333 | 310 | def test_push_accepts_more5(self): |
|
334 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
335 | if self.isp.input_mode == 'cell': return | |
|
336 | ||
|
337 | 311 | isp = self.isp |
|
338 | 312 | isp.push('try:') |
|
339 | 313 | isp.push(' a = 5') |
|
340 | 314 | isp.push('except:') |
|
341 | 315 | isp.push(' raise') |
|
316 | # We want to be able to add an else: block at this point, so it should | |
|
317 | # wait for a blank line. | |
|
342 | 318 | self.assertTrue(isp.push_accepts_more()) |
|
343 | 319 | |
|
344 | 320 | def test_continuation(self): |
@@ -431,7 +407,7 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
431 | 407 | """ |
|
432 | 408 | |
|
433 | 409 | def setUp(self): |
|
434 |
self.isp = isp.IPythonInputSplitter( |
|
|
410 | self.isp = isp.IPythonInputSplitter() | |
|
435 | 411 | |
|
436 | 412 | def test_syntax(self): |
|
437 | 413 | """Call all single-line syntax tests from the main object""" |
@@ -467,32 +443,6 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
467 | 443 | self.assertEqual(out.rstrip(), out_t) |
|
468 | 444 | self.assertEqual(out_raw.rstrip(), raw) |
|
469 | 445 | |
|
470 | ||
|
471 | class BlockIPythonInputTestCase(IPythonInputTestCase): | |
|
472 | ||
|
473 | # Deactivate tests that don't make sense for the block mode | |
|
474 | test_push3 = test_split = lambda s: None | |
|
475 | ||
|
476 | def setUp(self): | |
|
477 | self.isp = isp.IPythonInputSplitter(input_mode='cell') | |
|
478 | ||
|
479 | def test_syntax_multiline(self): | |
|
480 | isp = self.isp | |
|
481 | for example in syntax_ml.itervalues(): | |
|
482 | raw_parts = [] | |
|
483 | out_t_parts = [] | |
|
484 | for line_pairs in example: | |
|
485 | raw_parts, out_t_parts = zip(*line_pairs) | |
|
486 | ||
|
487 | raw = '\n'.join(r for r in raw_parts if r is not None) | |
|
488 | out_t = '\n'.join(o for o in out_t_parts if o is not None) | |
|
489 | ||
|
490 | isp.push(raw) | |
|
491 | out, out_raw = isp.source_raw_reset() | |
|
492 | # Match ignoring trailing whitespace | |
|
493 | self.assertEqual(out.rstrip(), out_t.rstrip()) | |
|
494 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) | |
|
495 | ||
|
496 | 446 | def test_syntax_multiline_cell(self): |
|
497 | 447 | isp = self.isp |
|
498 | 448 | for example in syntax_ml.itervalues(): |
@@ -588,39 +538,35 b' class CellMagicsCommon(object):' | |||
|
588 | 538 | out = sp.source_reset() |
|
589 | 539 | ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n" |
|
590 | 540 | nt.assert_equal(out, py3compat.u_format(ref)) |
|
541 | ||
|
542 | def test_cellmagic_help(self): | |
|
543 | self.sp.push('%%cellm?') | |
|
544 | nt.assert_false(self.sp.push_accepts_more()) | |
|
591 | 545 | |
|
592 | 546 | def tearDown(self): |
|
593 | 547 | self.sp.reset() |
|
594 | 548 | |
|
595 | 549 | |
|
596 | 550 | class CellModeCellMagics(CellMagicsCommon, unittest.TestCase): |
|
597 |
sp = isp.IPythonInputSplitter(input_ |
|
|
551 | sp = isp.IPythonInputSplitter(line_input_checker=False) | |
|
598 | 552 | |
|
599 | 553 | def test_incremental(self): |
|
600 | 554 | sp = self.sp |
|
601 |
s |
|
|
602 | sp.push(src) | |
|
555 | sp.push('%%cellm firstline\n') | |
|
603 | 556 | nt.assert_true(sp.push_accepts_more()) #1 |
|
604 | src += '\n' | |
|
605 | sp.push(src) | |
|
606 | # Note: if we ever change the logic to allow full blank lines (see | |
|
607 | # _handle_cell_magic), then the following test should change to true | |
|
608 |
nt.assert_ |
|
|
609 | # By now, even with full blanks allowed, a second blank should signal | |
|
610 | # the end. For now this test is only a redundancy safety, but don't | |
|
611 | # delete it in case we change our mind and the previous one goes to | |
|
612 | # true. | |
|
613 | src += '\n' | |
|
614 | sp.push(src) | |
|
615 | nt.assert_false(sp.push_accepts_more()) #3 | |
|
616 | ||
|
557 | sp.push('line2\n') | |
|
558 | nt.assert_true(sp.push_accepts_more()) #2 | |
|
559 | sp.push('\n') | |
|
560 | # This should accept a blank line and carry on until the cell is reset | |
|
561 | nt.assert_true(sp.push_accepts_more()) #3 | |
|
617 | 562 | |
|
618 | 563 | class LineModeCellMagics(CellMagicsCommon, unittest.TestCase): |
|
619 |
sp = isp.IPythonInputSplitter(input_ |
|
|
564 | sp = isp.IPythonInputSplitter(line_input_checker=True) | |
|
620 | 565 | |
|
621 | 566 | def test_incremental(self): |
|
622 | 567 | sp = self.sp |
|
623 | 568 | sp.push('%%cellm line2\n') |
|
624 | 569 | nt.assert_true(sp.push_accepts_more()) #1 |
|
625 | 570 | sp.push('\n') |
|
571 | # In this case, a blank line should end the cell magic | |
|
626 | 572 | nt.assert_false(sp.push_accepts_more()) #2 |
@@ -19,9 +19,9 b' def transform_and_reset(transformer):' | |||
|
19 | 19 | return transform |
|
20 | 20 | |
|
21 | 21 | # Transformer tests |
|
22 | def transform_checker(tests, transformer): | |
|
22 | def transform_checker(tests, transformer, **kwargs): | |
|
23 | 23 | """Utility to loop over test inputs""" |
|
24 | transformer = transformer() | |
|
24 | transformer = transformer(**kwargs) | |
|
25 | 25 | try: |
|
26 | 26 | for inp, tr in tests: |
|
27 | 27 | if inp is None: |
@@ -223,7 +223,7 b' syntax_ml = \\' | |||
|
223 | 223 | ], |
|
224 | 224 | [(u'%%bar 123', None), |
|
225 | 225 | (u'hello', None), |
|
226 |
( |
|
|
226 | (None , u_fmt("get_ipython().run_cell_magic({u}'bar', {u}'123', {u}'hello')")), | |
|
227 | 227 | ], |
|
228 | 228 | ], |
|
229 | 229 | |
@@ -348,6 +348,12 b' def test_escaped_paren():' | |||
|
348 | 348 | def test_cellmagic(): |
|
349 | 349 | for example in syntax_ml['cellmagic']: |
|
350 | 350 | transform_checker(example, ipt.cellmagic) |
|
351 | ||
|
352 | line_example = [(u'%%bar 123', None), | |
|
353 | (u'hello', None), | |
|
354 | (u'' , u_fmt("get_ipython().run_cell_magic({u}'bar', {u}'123', {u}'hello')")), | |
|
355 | ] | |
|
356 | transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True) | |
|
351 | 357 | |
|
352 | 358 | def test_has_comment(): |
|
353 | 359 | tests = [('text', False), |
@@ -146,7 +146,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
146 | 146 | self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None) |
|
147 | 147 | self._hidden = False |
|
148 | 148 | self._highlighter = FrontendHighlighter(self) |
|
149 |
self._input_splitter = self._input_splitter_class( |
|
|
149 | self._input_splitter = self._input_splitter_class() | |
|
150 | 150 | self._kernel_manager = None |
|
151 | 151 | self._request_info = {} |
|
152 | 152 | self._request_info['execute'] = {}; |
@@ -204,6 +204,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
204 | 204 | prompt created. When triggered by an Enter/Return key press, |
|
205 | 205 | 'interactive' is True; otherwise, it is False. |
|
206 | 206 | """ |
|
207 | self._input_splitter.reset() | |
|
207 | 208 | complete = self._input_splitter.push(source) |
|
208 | 209 | if interactive: |
|
209 | 210 | complete = not self._input_splitter.push_accepts_more() |
@@ -82,7 +82,7 b' def get_pasted_lines(sentinel, l_input=py3compat.input):' | |||
|
82 | 82 | class TerminalMagics(Magics): |
|
83 | 83 | def __init__(self, shell): |
|
84 | 84 | super(TerminalMagics, self).__init__(shell) |
|
85 |
self.input_splitter = IPythonInputSplitter( |
|
|
85 | self.input_splitter = IPythonInputSplitter() | |
|
86 | 86 | |
|
87 | 87 | def cleanup_input(self, block): |
|
88 | 88 | """Apply all possible IPython cleanups to an input block. |
@@ -35,6 +35,14 b' in attributes of :class:`~IPython.core.inputsplitter.IPythonInputSplitter`:' | |||
|
35 | 35 | passed to these, but note that function and class *definitions* are still a |
|
36 | 36 | series of separate statements. IPython does not use any of these by default. |
|
37 | 37 | |
|
38 | An InteractiveShell instance actually has two | |
|
39 | :class:`~IPython.core.inputsplitter.IPythonInputSplitter` instances, as the | |
|
40 | attributes :attr:`~IPython.core.interactiveshell.InteractiveShell.input_splitter`, | |
|
41 | to tell when a block of input is complete, and | |
|
42 | :attr:`~IPython.core.interactiveshell.InteractiveShell.input_transformer_manager`, | |
|
43 | to transform complete cells. If you add a transformer, you should make sure that | |
|
44 | it gets added to both. | |
|
45 | ||
|
38 | 46 | Stateless transformations |
|
39 | 47 | ------------------------- |
|
40 | 48 |
General Comments 0
You need to be logged in to leave comments.
Login now