@@ -263,6 +263,7 @@ def reset_execution_trackers(self):
263
263
"""Resets any per-execution trackers.
264
264
"""
265
265
self .kc = None
266
+ self .code_cells_executed = 0
266
267
self ._display_id_map = {}
267
268
self .widget_state = {}
268
269
self .widget_buffers = {}
@@ -342,7 +343,6 @@ def setup_kernel(self, **kwargs):
342
343
self .kc .stop_channels ()
343
344
self .kc = None
344
345
345
- # TODO: Remove non-kwarg arguments
346
346
def execute (self , ** kwargs ):
347
347
"""
348
348
Executes each code cell.
@@ -357,7 +357,9 @@ def execute(self, **kwargs):
357
357
with self .setup_kernel (** kwargs ):
358
358
self .log .info ("Executing notebook with kernel: %s" % self .kernel_name )
359
359
for index , cell in enumerate (self .nb .cells ):
360
- self .execute_cell (cell , index )
360
+ # Ignore `'execution_count' in content` as it's always 1
361
+ # when store_history is False
362
+ self .execute_cell (cell , index , execution_count = self .code_cells_executed + 1 )
361
363
info_msg = self ._wait_for_reply (self .kc .kernel_info ())
362
364
self .nb .metadata ['language_info' ] = info_msg ['content' ]['language_info' ]
363
365
self .set_widgets_metadata ()
@@ -384,30 +386,6 @@ def set_widgets_metadata(self):
384
386
if buffers :
385
387
widget ['buffers' ] = buffers
386
388
387
- def execute_cell (self , cell , cell_index , store_history = True ):
388
- """
389
- Executes a single code cell.
390
-
391
- To execute all cells see :meth:`execute`.
392
- """
393
- if cell .cell_type != 'code' or not cell .source .strip ():
394
- return cell
395
-
396
- reply , outputs = self .run_cell (cell , cell_index , store_history )
397
- # Backwards compatibility for processes that wrap run_cell
398
- cell .outputs = outputs
399
-
400
- cell_allows_errors = self .allow_errors or "raises-exception" in cell .metadata .get (
401
- "tags" , []
402
- )
403
-
404
- if self .force_raise_errors or not cell_allows_errors :
405
- if (reply is not None ) and reply ['content' ]['status' ] == 'error' :
406
- raise CellExecutionError .from_cell_and_msg (cell , reply ['content' ])
407
-
408
- self .nb ['cells' ][cell_index ] = cell
409
- return cell
410
-
411
389
def _update_display_id (self , display_id , msg ):
412
390
"""Update outputs with a given display_id"""
413
391
if display_id not in self ._display_id_map :
@@ -499,11 +477,59 @@ def _passed_deadline(self, deadline):
499
477
return True
500
478
return False
501
479
502
- def run_cell (self , cell , cell_index = 0 , store_history = False ):
480
+ def _check_raise_for_error (self , cell , exec_reply ):
481
+ cell_allows_errors = self .allow_errors or "raises-exception" in cell .metadata .get (
482
+ "tags" , []
483
+ )
484
+
485
+ if self .force_raise_errors or not cell_allows_errors :
486
+ if (exec_reply is not None ) and exec_reply ['content' ]['status' ] == 'error' :
487
+ raise CellExecutionError .from_cell_and_msg (cell , exec_reply ['content' ])
488
+
489
+ def execute_cell (self , cell , cell_index , execution_count = None , store_history = True ):
490
+ """
491
+ Executes a single code cell.
492
+
493
+ To execute all cells see :meth:`execute`.
494
+
495
+ Parameters
496
+ ----------
497
+ cell : nbformat.NotebookNode
498
+ The cell which is currently being processed.
499
+ cell_index : int
500
+ The position of the cell within the notebook object.
501
+ execution_count : int
502
+ The execution count to be assigned to the cell (default: Use kernel response)
503
+ store_history : bool
504
+ Determines if history should be stored in the kernel (default: False).
505
+ Specific to ipython kernels, which can store command histories.
506
+
507
+ Returns
508
+ -------
509
+ output : dict
510
+ The execution output payload (or None for no output).
511
+
512
+ Raises
513
+ ------
514
+ CellExecutionError
515
+ If execution failed and should raise an exception, this will be raised
516
+ with defaults about the failure.
517
+
518
+ Returns
519
+ -------
520
+ cell : NotebookNode
521
+ The cell which was just processed.
522
+ """
523
+ if cell .cell_type != 'code' or not cell .source .strip ():
524
+ self .log .debug ("Skipping non-executing cell %s" , cell_index )
525
+ return cell
526
+
527
+ self .log .debug ("Executing cell:\n %s" , cell .source )
503
528
parent_msg_id = self .kc .execute (
504
529
cell .source , store_history = store_history , stop_on_error = not self .allow_errors
505
530
)
506
- self .log .debug ("Executing cell:\n %s" , cell .source )
531
+ # We launched a code cell to execute
532
+ self .code_cells_executed += 1
507
533
exec_timeout = self ._get_timeout (cell )
508
534
deadline = None
509
535
if exec_timeout is not None :
@@ -570,8 +596,11 @@ def run_cell(self, cell, cell_index=0, store_history=False):
570
596
except CellExecutionComplete :
571
597
more_output = False
572
598
573
- # Return cell.outputs still for backwards compatibility
574
- return exec_reply , cell .outputs
599
+ if execution_count :
600
+ cell ['execution_count' ] = execution_count
601
+ self ._check_raise_for_error (cell , exec_reply )
602
+ self .nb ['cells' ][cell_index ] = cell
603
+ return cell
575
604
576
605
def process_message (self , msg , cell , cell_index ):
577
606
"""
0 commit comments