##// END OF EJS Templates
Also catch SyntaxErrors from InputTransformers in run_cell()...
Volker Braun -
Show More
@@ -0,0 +1,58 b''
1 # coding: utf-8
2 """Tests for the IPython terminal"""
3
4 import os
5 import tempfile
6 import shutil
7
8 import nose.tools as nt
9
10 from IPython.testing.tools import make_tempfile, ipexec
11
12
13 TEST_SYNTAX_ERROR_CMDS = """
14 from IPython.core.inputtransformer import InputTransformer
15
16 %cpaste
17 class SyntaxErrorTransformer(InputTransformer):
18
19 def push(self, line):
20 pos = line.find('syntaxerror')
21 if pos >= 0:
22 e = SyntaxError('input contains "syntaxerror"')
23 e.text = line
24 e.offset = pos + 1
25 raise e
26 return line
27
28 def reset(self):
29 pass
30 --
31
32 ip = get_ipython()
33 transformer = SyntaxErrorTransformer()
34 ip.input_splitter.python_line_transforms.append(transformer)
35 ip.input_transformer_manager.python_line_transforms.append(transformer)
36
37 # now the actual commands
38 1234
39 2345 # syntaxerror <- triggered here
40 3456
41 """
42
43 def test_syntax_error():
44 """Check that the IPython terminal does not abort if a SyntaxError is raised in an InputTransformer"""
45 try:
46 tmp = tempfile.mkdtemp()
47 filename = os.path.join(tmp, 'test_syntax_error.py')
48 with open(filename, 'w') as f:
49 f.write(TEST_SYNTAX_ERROR_CMDS)
50 out, err = ipexec(filename, pipe=True)
51 nt.assert_equal(err, '')
52 nt.assert_in('1234', out)
53 nt.assert_in(' 2345 # syntaxerror <- triggered here', out)
54 nt.assert_in(' ^', out)
55 nt.assert_in('SyntaxError: input contains "syntaxerror"', out)
56 nt.assert_in('3456', out)
57 finally:
58 shutil.rmtree(tmp)
@@ -47,6 +47,9 b' class InputTransformer(with_metaclass(abc.ABCMeta, object)):'
47 47 input or None if the transformer is waiting for more input.
48 48
49 49 Must be overridden by subclasses.
50
51 Implementations may raise ``SyntaxError`` if the input is invalid. No
52 other exceptions may be raised.
50 53 """
51 54 pass
52 55
@@ -2632,7 +2632,12 b' class InteractiveShell(SingletonConfigurable):'
2632 2632 if silent:
2633 2633 store_history = False
2634 2634
2635 self.input_transformer_manager.push(raw_cell)
2635 prefilter_failed = False
2636 try:
2637 self.input_transformer_manager.push(raw_cell)
2638 except SyntaxError:
2639 self.showtraceback()
2640 prefilter_failed = True
2636 2641 cell = self.input_transformer_manager.source_reset()
2637 2642
2638 2643 # Our own compiler remembers the __future__ environment. If we want to
@@ -2641,8 +2646,7 b' class InteractiveShell(SingletonConfigurable):'
2641 2646 compiler = self.compile if shell_futures else CachingCompiler()
2642 2647
2643 2648 with self.builtin_trap:
2644 prefilter_failed = False
2645 if len(cell.splitlines()) == 1:
2649 if not prefilter_failed and len(cell.splitlines()) == 1:
2646 2650 try:
2647 2651 # use prefilter_lines to handle trailing newlines
2648 2652 # restore trailing newline for ast.parse
@@ -3,13 +3,9 b''
3 3
4 4 import os
5 5 import tempfile
6 import shutil
7
8 import nose.tools as nt
9 6
10 7 from IPython.core.application import BaseIPythonApplication
11 8 from IPython.testing import decorators as dec
12 from IPython.testing.tools import make_tempfile, ipexec
13 9 from IPython.utils import py3compat
14 10
15 11 @dec.onlyif_unicode_paths
@@ -52,46 +48,3 b' def test_unicode_ipdir():'
52 48 os.environ["IPYTHONDIR"] = old_ipdir1
53 49 if old_ipdir2:
54 50 os.environ["IPYTHONDIR"] = old_ipdir2
55
56
57
58 TEST_SYNTAX_ERROR_CMDS = """
59 from IPython.core.inputtransformer import InputTransformer
60
61 %cpaste
62 class SyntaxErrorTransformer(InputTransformer):
63
64 def push(self, line):
65 if 'syntaxerror' in line:
66 raise SyntaxError('in input '+line)
67 return line
68
69 def reset(self):
70 pass
71 --
72
73 ip = get_ipython()
74 transformer = SyntaxErrorTransformer()
75 ip.input_splitter.python_line_transforms.append(transformer)
76 ip.input_transformer_manager.python_line_transforms.append(transformer)
77
78 # now the actual commands
79 1234
80 2345 # syntaxerror <- triggered here
81 3456
82 """
83
84 def test_syntax_error():
85 """Check that IPython does not abort if a SyntaxError is raised in an InputTransformer"""
86 try:
87 tmp = tempfile.mkdtemp()
88 filename = os.path.join(tmp, 'test_syntax_error.py')
89 with open(filename, 'w') as f:
90 f.write(TEST_SYNTAX_ERROR_CMDS)
91 out, err = ipexec(filename, pipe=True)
92 nt.assert_equal(err, '')
93 nt.assert_in('1234', out)
94 nt.assert_in('SyntaxError: in input 2345 # syntaxerror <- triggered here', out)
95 nt.assert_in('3456', out)
96 finally:
97 shutil.rmtree(tmp)
@@ -33,6 +33,7 b' from os.path import join'
33 33 import nose.tools as nt
34 34
35 35 # Our own
36 from IPython.core.inputtransformer import InputTransformer
36 37 from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths
37 38 from IPython.testing import tools as tt
38 39 from IPython.utils import io
@@ -674,4 +675,41 b' def test_user_expression():'
674 675
675 676
676 677
678 class TestSyntaxErrorTransformer(unittest.TestCase):
679 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
680
681 class SyntaxErrorTransformer(InputTransformer):
682
683 def push(self, line):
684 pos = line.find('syntaxerror')
685 if pos >= 0:
686 e = SyntaxError('input contains "syntaxerror"')
687 e.text = line
688 e.offset = pos + 1
689 raise e
690 return line
691
692 def reset(self):
693 pass
694
695 def setUp(self):
696 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
697 ip.input_splitter.python_line_transforms.append(self.transformer)
698 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
699
700 def tearDown(self):
701 ip.input_splitter.python_line_transforms.remove(self.transformer)
702 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
703
704 def test_syntaxerror_input_transformer(self):
705 with tt.AssertPrints('1234'):
706 ip.run_cell('1234')
707 with tt.AssertPrints('SyntaxError: invalid syntax'):
708 ip.run_cell('1 2 3') # plain python syntax error
709 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
710 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
711 with tt.AssertPrints('3456'):
712 ip.run_cell('3456')
713
714
677 715
General Comments 0
You need to be logged in to leave comments. Login now