Show More
@@ -403,7 +403,7 b' define([' | |||
|
403 | 403 | * Execute current code cell to the kernel |
|
404 | 404 | * @method execute |
|
405 | 405 | */ |
|
406 | CodeCell.prototype.execute = function () { | |
|
406 | CodeCell.prototype.execute = function (skip_exceptions) { | |
|
407 | 407 | if (!this.kernel || !this.kernel.is_connected()) { |
|
408 | 408 | console.log("Can't execute, kernel is not connected."); |
|
409 | 409 | return; |
@@ -411,6 +411,10 b' define([' | |||
|
411 | 411 | |
|
412 | 412 | this.active_output_area.clear_output(false, true); |
|
413 | 413 | |
|
414 | if (skip_exceptions === undefined) { | |
|
415 | skip_exceptions = false; | |
|
416 | } | |
|
417 | ||
|
414 | 418 | // Clear widget area |
|
415 | 419 | for (var i = 0; i < this.widget_views.length; i++) { |
|
416 | 420 | var view = this.widget_views[i]; |
@@ -434,7 +438,8 b' define([' | |||
|
434 | 438 | var callbacks = this.get_callbacks(); |
|
435 | 439 | |
|
436 | 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 | 443 | if (old_msg_id) { |
|
439 | 444 | delete CodeCell.msg_cells[old_msg_id]; |
|
440 | 445 | } |
@@ -75,4 +75,39 b' casper.notebook_test(function () {' | |||
|
75 | 75 | var result = this.get_output_cell(0); |
|
76 | 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 | 197 | # Methods to send specific messages on channels |
|
198 | 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 | 200 | """Execute code in the kernel. |
|
201 | 201 | |
|
202 | 202 | Parameters |
@@ -224,6 +224,9 b' class KernelClient(ConnectionFileMixin):' | |||
|
224 | 224 | If raw_input is called from code executed from such a frontend, a |
|
225 | 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 | 230 | Returns |
|
228 | 231 | ------- |
|
229 | 232 | The msg_id of the message sent. |
@@ -243,7 +246,7 b' class KernelClient(ConnectionFileMixin):' | |||
|
243 | 246 | # not in Session. |
|
244 | 247 | content = dict(code=code, silent=silent, store_history=store_history, |
|
245 | 248 | user_expressions=user_expressions, |
|
246 | allow_stdin=allow_stdin, | |
|
249 | allow_stdin=allow_stdin, skip_exceptions=skip_exceptions | |
|
247 | 250 | ) |
|
248 | 251 | msg = self.session.msg('execute_request', content) |
|
249 | 252 | self.shell_channel.send(msg) |
@@ -303,6 +303,24 b' def test_execute_inc():' | |||
|
303 | 303 | count_2 = reply['execution_count'] |
|
304 | 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 | 325 | def test_user_expressions(): |
|
308 | 326 | flush_channels() |
@@ -348,6 +348,11 b' class Kernel(SingletonConfigurable):' | |||
|
348 | 348 | self.log.error("%s", parent) |
|
349 | 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 | 356 | md = self._make_metadata(parent['metadata']) |
|
352 | 357 | |
|
353 | 358 | # Re-broadcast our input for the benefit of listening clients, and |
@@ -382,11 +387,11 b' class Kernel(SingletonConfigurable):' | |||
|
382 | 387 | |
|
383 | 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 | 391 | self._abort_queues() |
|
387 | 392 | |
|
388 | 393 | def do_execute(self, code, silent, store_history=True, |
|
389 |
user_exp |
|
|
394 | user_expressions=None, allow_stdin=False): | |
|
390 | 395 | """Execute user code. Must be overridden by subclasses. |
|
391 | 396 | """ |
|
392 | 397 | raise NotImplementedError |
@@ -281,6 +281,10 b' Message type: ``execute_request``::' | |||
|
281 | 281 | # If raw_input is called from code executed from such a frontend, |
|
282 | 282 | # a StdinNotImplementedError will be raised. |
|
283 | 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 | 290 | .. versionchanged:: 5.0 |
General Comments 0
You need to be logged in to leave comments.
Login now