##// END OF EJS Templates
Allow InputTransformers to raise SyntaxErrors...
Volker Braun -
Show More
@@ -3,9 +3,13 b''
3
3
4 import os
4 import os
5 import tempfile
5 import tempfile
6 import shutil
7
8 import nose.tools as nt
6
9
7 from IPython.core.application import BaseIPythonApplication
10 from IPython.core.application import BaseIPythonApplication
8 from IPython.testing import decorators as dec
11 from IPython.testing import decorators as dec
12 from IPython.testing.tools import make_tempfile, ipexec
9 from IPython.utils import py3compat
13 from IPython.utils import py3compat
10
14
11 @dec.onlyif_unicode_paths
15 @dec.onlyif_unicode_paths
@@ -48,3 +52,46 b' def test_unicode_ipdir():'
48 os.environ["IPYTHONDIR"] = old_ipdir1
52 os.environ["IPYTHONDIR"] = old_ipdir1
49 if old_ipdir2:
53 if old_ipdir2:
50 os.environ["IPYTHONDIR"] = old_ipdir2
54 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)
@@ -541,8 +541,13 b' class TerminalInteractiveShell(InteractiveShell):'
541 # asynchronously by signal handlers, for example.
541 # asynchronously by signal handlers, for example.
542 self.showtraceback()
542 self.showtraceback()
543 else:
543 else:
544 self.input_splitter.push(line)
544 try:
545 more = self.input_splitter.push_accepts_more()
545 self.input_splitter.push(line)
546 more = self.input_splitter.push_accepts_more()
547 except SyntaxError:
548 self.showsyntaxerror()
549 self.input_splitter.reset()
550 more = False
546 if (self.SyntaxTB.last_syntax_error and
551 if (self.SyntaxTB.last_syntax_error and
547 self.autoedit_syntax):
552 self.autoedit_syntax):
548 self.edit_syntax_error()
553 self.edit_syntax_error()
@@ -173,7 +173,7 b' def get_ipython_cmd(as_string=False):'
173
173
174 return ipython_cmd
174 return ipython_cmd
175
175
176 def ipexec(fname, options=None):
176 def ipexec(fname, options=None, pipe=False):
177 """Utility to call 'ipython filename'.
177 """Utility to call 'ipython filename'.
178
178
179 Starts IPython with a minimal and safe configuration to make startup as fast
179 Starts IPython with a minimal and safe configuration to make startup as fast
@@ -189,6 +189,9 b' def ipexec(fname, options=None):'
189 options : optional, list
189 options : optional, list
190 Extra command-line flags to be passed to IPython.
190 Extra command-line flags to be passed to IPython.
191
191
192 pipe : optional, boolean
193 Pipe fname into IPython as stdin instead of calling it as external file
194
192 Returns
195 Returns
193 -------
196 -------
194 (stdout, stderr) of ipython subprocess.
197 (stdout, stderr) of ipython subprocess.
@@ -208,8 +211,12 b' def ipexec(fname, options=None):'
208 ipython_cmd = get_ipython_cmd()
211 ipython_cmd = get_ipython_cmd()
209 # Absolute path for filename
212 # Absolute path for filename
210 full_fname = os.path.join(test_dir, fname)
213 full_fname = os.path.join(test_dir, fname)
211 full_cmd = ipython_cmd + cmdargs + [full_fname]
214 if pipe:
212 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
215 full_cmd = ipython_cmd + cmdargs
216 p = Popen(full_cmd, stdin=open(full_fname), stdout=PIPE, stderr=PIPE)
217 else:
218 full_cmd = ipython_cmd + cmdargs + [full_fname]
219 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
213 out, err = p.communicate()
220 out, err = p.communicate()
214 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
221 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
215 # `import readline` causes 'ESC[?1034h' to be output sometimes,
222 # `import readline` causes 'ESC[?1034h' to be output sometimes,
General Comments 0
You need to be logged in to leave comments. Login now