##// 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).
@@ -403,7 +402,7 b' class TokenTransformers:'
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
424
423 def transform_cell(self, cell: str):
425 def transform_cell(cell):
426 if not cell.endswith('\n'):
424 if not cell.endswith('\n'):
427 cell += '\n' # Ensure every line has a newline
425 cell += '\n' # Ensure every line has a newline
428 lines = cell.splitlines(keepends=True)
426 lines = cell.splitlines(keepends=True)
429 for transform in line_transforms:
427 for transform in self.line_transforms:
430 #print(transform, lines)
428 #print(transform, lines)
431 lines = transform(lines)
429 lines = transform(lines)
432
430
433 lines = TokenTransformers()(lines)
431 lines = self.do_token_transforms(lines)
434 return ''.join(lines)
432 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