Show More
@@ -403,7 +403,7 b' define([' | |||||
403 | * Execute current code cell to the kernel |
|
403 | * Execute current code cell to the kernel | |
404 | * @method execute |
|
404 | * @method execute | |
405 | */ |
|
405 | */ | |
406 | CodeCell.prototype.execute = function () { |
|
406 | CodeCell.prototype.execute = function (skip_exceptions) { | |
407 | if (!this.kernel || !this.kernel.is_connected()) { |
|
407 | if (!this.kernel || !this.kernel.is_connected()) { | |
408 | console.log("Can't execute, kernel is not connected."); |
|
408 | console.log("Can't execute, kernel is not connected."); | |
409 | return; |
|
409 | return; | |
@@ -411,6 +411,10 b' define([' | |||||
411 |
|
411 | |||
412 | this.active_output_area.clear_output(false, true); |
|
412 | this.active_output_area.clear_output(false, true); | |
413 |
|
413 | |||
|
414 | if (skip_exceptions === undefined) { | |||
|
415 | skip_exceptions = false; | |||
|
416 | } | |||
|
417 | ||||
414 | // Clear widget area |
|
418 | // Clear widget area | |
415 | for (var i = 0; i < this.widget_views.length; i++) { |
|
419 | for (var i = 0; i < this.widget_views.length; i++) { | |
416 | var view = this.widget_views[i]; |
|
420 | var view = this.widget_views[i]; | |
@@ -434,7 +438,8 b' define([' | |||||
434 | var callbacks = this.get_callbacks(); |
|
438 | var callbacks = this.get_callbacks(); | |
435 |
|
439 | |||
436 | var old_msg_id = this.last_msg_id; |
|
440 | var old_msg_id = this.last_msg_id; | |
437 |
this.last_msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true |
|
441 | this.last_msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true, | |
|
442 | skip_exceptions : skip_exceptions}); | |||
438 | if (old_msg_id) { |
|
443 | if (old_msg_id) { | |
439 | delete CodeCell.msg_cells[old_msg_id]; |
|
444 | delete CodeCell.msg_cells[old_msg_id]; | |
440 | } |
|
445 | } |
@@ -75,4 +75,39 b' casper.notebook_test(function () {' | |||||
75 | var result = this.get_output_cell(0); |
|
75 | var result = this.get_output_cell(0); | |
76 | this.test.assertEquals(result.text, '13\n', 'cell execute (using "play" toolbar button)') |
|
76 | this.test.assertEquals(result.text, '13\n', 'cell execute (using "play" toolbar button)') | |
77 | }); |
|
77 | }); | |
|
78 | ||||
|
79 | // run code with skip_exception | |||
|
80 | this.thenEvaluate(function () { | |||
|
81 | var cell0 = IPython.notebook.get_cell(0); | |||
|
82 | cell0.set_text('raise IOError'); | |||
|
83 | IPython.notebook.insert_cell_below('code',0); | |||
|
84 | var cell1 = IPython.notebook.get_cell(1); | |||
|
85 | cell1.set_text('a=14; print(a)'); | |||
|
86 | cell0.execute(skip_exception=true); | |||
|
87 | cell1.execute(); | |||
|
88 | }); | |||
|
89 | ||||
|
90 | this.wait_for_output(1); | |||
|
91 | ||||
|
92 | this.then(function () { | |||
|
93 | var result = this.get_output_cell(1); | |||
|
94 | this.test.assertEquals(result.text, '14\n', 'cell execute, skip exceptions'); | |||
|
95 | }); | |||
|
96 | ||||
|
97 | this.thenEvaluate(function () { | |||
|
98 | var cell0 = IPython.notebook.get_cell(0); | |||
|
99 | cell0.set_text('raise IOError'); | |||
|
100 | IPython.notebook.insert_cell_below('code',0); | |||
|
101 | var cell1 = IPython.notebook.get_cell(1); | |||
|
102 | cell1.set_text('a=14; print(a)'); | |||
|
103 | cell0.execute(); | |||
|
104 | cell1.execute(); | |||
|
105 | }); | |||
|
106 | ||||
|
107 | this.wait_for_output(1); | |||
|
108 | ||||
|
109 | this.then(function () { | |||
|
110 | var result = this.get_output_cell(1); | |||
|
111 | this.test.assertNotEquals(result.text, '14\n', 'cell execute, skip exceptions'); | |||
|
112 | }); | |||
78 | }); |
|
113 | }); |
@@ -196,7 +196,7 b' class KernelClient(ConnectionFileMixin):' | |||||
196 |
|
196 | |||
197 | # Methods to send specific messages on channels |
|
197 | # Methods to send specific messages on channels | |
198 | def execute(self, code, silent=False, store_history=True, |
|
198 | def execute(self, code, silent=False, store_history=True, | |
199 | user_expressions=None, allow_stdin=None): |
|
199 | user_expressions=None, allow_stdin=None, skip_exceptions=False): | |
200 | """Execute code in the kernel. |
|
200 | """Execute code in the kernel. | |
201 |
|
201 | |||
202 | Parameters |
|
202 | Parameters | |
@@ -224,6 +224,9 b' class KernelClient(ConnectionFileMixin):' | |||||
224 | If raw_input is called from code executed from such a frontend, a |
|
224 | If raw_input is called from code executed from such a frontend, a | |
225 | StdinNotImplementedError will be raised. |
|
225 | StdinNotImplementedError will be raised. | |
226 |
|
226 | |||
|
227 | skip_exceptions: bool, optional (default False) | |||
|
228 | Flag whether to abort the execution queue, if an exception is encountered. | |||
|
229 | ||||
227 | Returns |
|
230 | Returns | |
228 | ------- |
|
231 | ------- | |
229 | The msg_id of the message sent. |
|
232 | The msg_id of the message sent. | |
@@ -243,7 +246,7 b' class KernelClient(ConnectionFileMixin):' | |||||
243 | # not in Session. |
|
246 | # not in Session. | |
244 | content = dict(code=code, silent=silent, store_history=store_history, |
|
247 | content = dict(code=code, silent=silent, store_history=store_history, | |
245 | user_expressions=user_expressions, |
|
248 | user_expressions=user_expressions, | |
246 | allow_stdin=allow_stdin, |
|
249 | allow_stdin=allow_stdin, skip_exceptions=skip_exceptions | |
247 | ) |
|
250 | ) | |
248 | msg = self.session.msg('execute_request', content) |
|
251 | msg = self.session.msg('execute_request', content) | |
249 | self.shell_channel.send(msg) |
|
252 | self.shell_channel.send(msg) |
@@ -303,6 +303,24 b' def test_execute_inc():' | |||||
303 | count_2 = reply['execution_count'] |
|
303 | count_2 = reply['execution_count'] | |
304 | nt.assert_equal(count_2, count+1) |
|
304 | nt.assert_equal(count_2, count+1) | |
305 |
|
305 | |||
|
306 | def test_execute_skip_exceptions(): | |||
|
307 | """execute request should not abort execution queue with skip_exceptions""" | |||
|
308 | flush_channels() | |||
|
309 | ||||
|
310 | KC.execute(code='raise IOError') | |||
|
311 | msg_id = KC.execute(code='print("Hallo")') | |||
|
312 | KC.get_shell_msg(timeout=TIMEOUT) | |||
|
313 | reply = KC.get_shell_msg(timeout=TIMEOUT) | |||
|
314 | nt.assert_equal(reply['content']['status'], 'aborted') | |||
|
315 | ||||
|
316 | flush_channels() | |||
|
317 | ||||
|
318 | KC.execute(code='raise IOError', skip_exceptions=True) | |||
|
319 | msg_id = KC.execute(code='print("Hallo")') | |||
|
320 | KC.get_shell_msg(timeout=TIMEOUT) | |||
|
321 | reply = KC.get_shell_msg(timeout=TIMEOUT) | |||
|
322 | nt.assert_equal(reply['content']['status'], 'ok') | |||
|
323 | ||||
306 |
|
324 | |||
307 | def test_user_expressions(): |
|
325 | def test_user_expressions(): | |
308 | flush_channels() |
|
326 | flush_channels() |
@@ -348,6 +348,11 b' class Kernel(SingletonConfigurable):' | |||||
348 | self.log.error("%s", parent) |
|
348 | self.log.error("%s", parent) | |
349 | return |
|
349 | return | |
350 |
|
350 | |||
|
351 | if u'skip_exceptions' in content and content[u'skip_exceptions'] is True: | |||
|
352 | skip_exceptions = True | |||
|
353 | else: | |||
|
354 | skip_exceptions = False | |||
|
355 | ||||
351 | md = self._make_metadata(parent['metadata']) |
|
356 | md = self._make_metadata(parent['metadata']) | |
352 |
|
357 | |||
353 | # Re-broadcast our input for the benefit of listening clients, and |
|
358 | # Re-broadcast our input for the benefit of listening clients, and | |
@@ -382,11 +387,11 b' class Kernel(SingletonConfigurable):' | |||||
382 |
|
387 | |||
383 | self.log.debug("%s", reply_msg) |
|
388 | self.log.debug("%s", reply_msg) | |
384 |
|
389 | |||
385 | if not silent and reply_msg['content']['status'] == u'error': |
|
390 | if not silent and reply_msg['content']['status'] == u'error' and not skip_exceptions: | |
386 | self._abort_queues() |
|
391 | self._abort_queues() | |
387 |
|
392 | |||
388 | def do_execute(self, code, silent, store_history=True, |
|
393 | def do_execute(self, code, silent, store_history=True, | |
389 |
user_exp |
|
394 | user_expressions=None, allow_stdin=False): | |
390 | """Execute user code. Must be overridden by subclasses. |
|
395 | """Execute user code. Must be overridden by subclasses. | |
391 | """ |
|
396 | """ | |
392 | raise NotImplementedError |
|
397 | raise NotImplementedError |
@@ -281,6 +281,10 b' Message type: ``execute_request``::' | |||||
281 | # If raw_input is called from code executed from such a frontend, |
|
281 | # If raw_input is called from code executed from such a frontend, | |
282 | # a StdinNotImplementedError will be raised. |
|
282 | # a StdinNotImplementedError will be raised. | |
283 | 'allow_stdin' : True, |
|
283 | 'allow_stdin' : True, | |
|
284 | ||||
|
285 | # A boolean flag, which, if True, does not abort the execution queue, if an exception is encountered. | |||
|
286 | # This allows the queued execution of multiple execute_requests, even if they generate exceptions. | |||
|
287 | 'skip_exceptions' : True, | |||
284 | } |
|
288 | } | |
285 |
|
289 | |||
286 | .. versionchanged:: 5.0 |
|
290 | .. versionchanged:: 5.0 |
General Comments 0
You need to be logged in to leave comments.
Login now