Show More
@@ -248,6 +248,22 b' class InputSplitter(object):' | |||||
248 | self.reset() |
|
248 | self.reset() | |
249 | return out |
|
249 | return out | |
250 |
|
250 | |||
|
251 | def is_complete(self, source): | |||
|
252 | """Return whether a block of code is ready to execute, or should be continued | |||
|
253 | ||||
|
254 | This is a non-stateful API, and will reset the state of this InputSplitter. | |||
|
255 | """ | |||
|
256 | self.reset() | |||
|
257 | try: | |||
|
258 | self.push(source) | |||
|
259 | return not self.push_accepts_more() | |||
|
260 | except SyntaxError: | |||
|
261 | # Transformers in IPythonInputSplitter can raise SyntaxError, | |||
|
262 | # which push() will not catch. | |||
|
263 | return True | |||
|
264 | finally: | |||
|
265 | self.reset() | |||
|
266 | ||||
251 | def push(self, lines): |
|
267 | def push(self, lines): | |
252 | """Push one or more lines of input. |
|
268 | """Push one or more lines of input. | |
253 |
|
269 |
@@ -355,6 +355,13 b' class InputSplitterTestCase(unittest.TestCase):' | |||||
355 | isp.push(r"(1 \ ") |
|
355 | isp.push(r"(1 \ ") | |
356 | self.assertFalse(isp.push_accepts_more()) |
|
356 | self.assertFalse(isp.push_accepts_more()) | |
357 |
|
357 | |||
|
358 | def test_is_complete(self): | |||
|
359 | isp = self.isp | |||
|
360 | assert isp.is_complete("a = 1") | |||
|
361 | assert not isp.is_complete("for a in range(5):") | |||
|
362 | assert isp.is_complete("raise = 2") # SyntaxError should mean complete | |||
|
363 | assert not isp.is_complete("a = [1,\n2,") | |||
|
364 | ||||
358 | class InteractiveLoopTestCase(unittest.TestCase): |
|
365 | class InteractiveLoopTestCase(unittest.TestCase): | |
359 | """Tests for an interactive loop like a python shell. |
|
366 | """Tests for an interactive loop like a python shell. | |
360 | """ |
|
367 | """ |
@@ -205,3 +205,19 b' def test_help_output():' | |||||
205 | """ipython kernel --help-all works""" |
|
205 | """ipython kernel --help-all works""" | |
206 | tt.help_all_output_test('kernel') |
|
206 | tt.help_all_output_test('kernel') | |
207 |
|
207 | |||
|
208 | def test_is_complete(): | |||
|
209 | with kernel() as kc: | |||
|
210 | # There are more test cases for this in core - here we just check | |||
|
211 | # that the kernel exposes the interface correctly. | |||
|
212 | kc.is_complete('2+2') | |||
|
213 | reply = kc.get_shell_msg(block=True, timeout=TIMEOUT) | |||
|
214 | assert reply['content']['complete'] | |||
|
215 | ||||
|
216 | # SyntaxError should mean it's complete | |||
|
217 | kc.is_complete('raise = 2') | |||
|
218 | reply = kc.get_shell_msg(block=True, timeout=TIMEOUT) | |||
|
219 | assert reply['content']['complete'] | |||
|
220 | ||||
|
221 | kc.is_complete('a = [1,\n2,') | |||
|
222 | reply = kc.get_shell_msg(block=True, timeout=TIMEOUT) | |||
|
223 | assert not reply['content']['complete'] |
@@ -229,6 +229,10 b' class IPythonKernel(KernelBase):' | |||||
229 | self.shell.exit_now = True |
|
229 | self.shell.exit_now = True | |
230 | return dict(status='ok', restart=restart) |
|
230 | return dict(status='ok', restart=restart) | |
231 |
|
231 | |||
|
232 | def do_is_complete(self, code): | |||
|
233 | complete = self.shell.input_transformer_manager.is_complete(code) | |||
|
234 | return {'complete': complete} | |||
|
235 | ||||
232 | def do_apply(self, content, bufs, msg_id, reply_metadata): |
|
236 | def do_apply(self, content, bufs, msg_id, reply_metadata): | |
233 | shell = self.shell |
|
237 | shell = self.shell | |
234 | try: |
|
238 | try: |
General Comments 0
You need to be logged in to leave comments.
Login now