##// END OF EJS Templates
Start integrating new input transformation machinery into InteractiveShell
Thomas Kluyver -
Show More
@@ -66,13 +66,6 b' def cell_magic(lines):'
66 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
66 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
67 % (magic_name, first_line, body)]
67 % (magic_name, first_line, body)]
68
68
69 line_transforms = [
70 leading_indent,
71 classic_prompt,
72 ipython_prompt,
73 cell_magic,
74 ]
75
76 # -----
69 # -----
77
70
78 def _find_assign_op(token_line):
71 def _find_assign_op(token_line):
@@ -378,16 +371,22 b' def show_linewise_tokens(s: str):'
378 for tokinfo in line:
371 for tokinfo in line:
379 print(" ", tokinfo)
372 print(" ", tokinfo)
380
373
381 class TokenTransformers:
374 class TransformerManager:
382 def __init__(self):
375 def __init__(self):
383 self.transformers = [
376 self.line_transforms = [
377 leading_indent,
378 classic_prompt,
379 ipython_prompt,
380 cell_magic,
381 ]
382 self.token_transformers = [
384 MagicAssign,
383 MagicAssign,
385 SystemAssign,
384 SystemAssign,
386 EscapedCommand,
385 EscapedCommand,
387 HelpEnd,
386 HelpEnd,
388 ]
387 ]
389
388
390 def do_one_transform(self, lines):
389 def do_one_token_transform(self, lines):
391 """Find and run the transform earliest in the code.
390 """Find and run the transform earliest in the code.
392
391
393 Returns (changed, lines).
392 Returns (changed, lines).
@@ -399,11 +398,11 b' class TokenTransformers:'
399 the transformed code is retokenised every time to identify the next
398 the transformed code is retokenised every time to identify the next
400 piece of special syntax. Hopefully long code cells are mostly valid
399 piece of special syntax. Hopefully long code cells are mostly valid
401 Python, not using lots of IPython special syntax, so this shouldn't be
400 Python, not using lots of IPython special syntax, so this shouldn't be
402 a performance issue.
401 a performance issue.
403 """
402 """
404 tokens_by_line = make_tokens_by_line(lines)
403 tokens_by_line = make_tokens_by_line(lines)
405 candidates = []
404 candidates = []
406 for transformer_cls in self.transformers:
405 for transformer_cls in self.token_transformers:
407 transformer = transformer_cls.find(tokens_by_line)
406 transformer = transformer_cls.find(tokens_by_line)
408 if transformer:
407 if transformer:
409 candidates.append(transformer)
408 candidates.append(transformer)
@@ -415,20 +414,19 b' class TokenTransformers:'
415 transformer = min(candidates, key=TokenTransformBase.sortby)
414 transformer = min(candidates, key=TokenTransformBase.sortby)
416 return True, transformer.transform(lines)
415 return True, transformer.transform(lines)
417
416
418 def __call__(self, lines):
417 def do_token_transforms(self, lines):
419 while True:
418 while True:
420 changed, lines = self.do_one_transform(lines)
419 changed, lines = self.do_one_token_transform(lines)
421 if not changed:
420 if not changed:
422 return lines
421 return lines
423
422
423 def transform_cell(self, cell: str):
424 if not cell.endswith('\n'):
425 cell += '\n' # Ensure every line has a newline
426 lines = cell.splitlines(keepends=True)
427 for transform in self.line_transforms:
428 #print(transform, lines)
429 lines = transform(lines)
424
430
425 def transform_cell(cell):
431 lines = self.do_token_transforms(lines)
426 if not cell.endswith('\n'):
432 return ''.join(lines)
427 cell += '\n' # Ensure every line has a newline
428 lines = cell.splitlines(keepends=True)
429 for transform in line_transforms:
430 #print(transform, lines)
431 lines = transform(lines)
432
433 lines = TokenTransformers()(lines)
434 return ''.join(lines)
@@ -339,10 +339,9 b' class InteractiveShell(SingletonConfigurable):'
339 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
339 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
340 (), {'line_input_checker': True})
340 (), {'line_input_checker': True})
341
341
342 # This InputSplitter instance is used to transform completed cells before
342 # Used to transform cells before running them.
343 # running them. It allows cell magics to contain blank lines.
343 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
344 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
344 ())
345 (), {'line_input_checker': False})
346
345
347 logstart = Bool(False, help=
346 logstart = Bool(False, help=
348 """
347 """
@@ -832,28 +832,22 b' def test_user_expression():'
832 class TestSyntaxErrorTransformer(unittest.TestCase):
832 class TestSyntaxErrorTransformer(unittest.TestCase):
833 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
833 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
834
834
835 class SyntaxErrorTransformer(InputTransformer):
835 @staticmethod
836
836 def transformer(lines):
837 def push(self, line):
837 for line in lines:
838 pos = line.find('syntaxerror')
838 pos = line.find('syntaxerror')
839 if pos >= 0:
839 if pos >= 0:
840 e = SyntaxError('input contains "syntaxerror"')
840 e = SyntaxError('input contains "syntaxerror"')
841 e.text = line
841 e.text = line
842 e.offset = pos + 1
842 e.offset = pos + 1
843 raise e
843 raise e
844 return line
844 return lines
845
846 def reset(self):
847 pass
848
845
849 def setUp(self):
846 def setUp(self):
850 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
847 ip.input_transformer_manager.line_transforms.append(self.transformer)
851 ip.input_splitter.python_line_transforms.append(self.transformer)
852 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
853
848
854 def tearDown(self):
849 def tearDown(self):
855 ip.input_splitter.python_line_transforms.remove(self.transformer)
850 ip.input_transformer_manager.line_transforms.remove(self.transformer)
856 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
857
851
858 def test_syntaxerror_input_transformer(self):
852 def test_syntaxerror_input_transformer(self):
859 with tt.AssertPrints('1234'):
853 with tt.AssertPrints('1234'):
General Comments 0
You need to be logged in to leave comments. Login now