11"""
22@file
3- @brief Modified version of `runipy.notebook_runner <https://github.com/paulgb/runipy/blob/master/runipy/notebook_runner.py>`_.
3+ @brief Modified version of `runipy.notebook_runner
4+ <https://github.com/paulgb/runipy/blob/master/runipy/notebook_runner.py>`_.
45"""
56
67import base64
@@ -127,10 +128,11 @@ def __init__(self, nb, profile_dir=None, working_dir=None,
127128 self .code_init = code_init
128129 self ._filename = filename if filename is not None else "memory"
129130 self .replacements = replacements
130- self .init_args = dict (profile_dir = profile_dir , working_dir = working_dir ,
131- comment = comment , fLOG = fLOG , theNotebook = theNotebook , code_init = code_init ,
132- kernel_name = "python" , log_level = "30" , extended_args = None ,
133- kernel = kernel , filename = filename , replacements = replacements )
131+ self .init_args = dict (
132+ profile_dir = profile_dir , working_dir = working_dir ,
133+ comment = comment , fLOG = fLOG , theNotebook = theNotebook , code_init = code_init ,
134+ kernel_name = "python" , log_level = "30" , extended_args = None ,
135+ kernel = kernel , filename = filename , replacements = replacements )
134136 args = []
135137
136138 if profile_dir :
@@ -161,7 +163,7 @@ def __init__(self, nb, profile_dir=None, working_dir=None,
161163 "ignore" , category = ResourceWarning )
162164 self .km .start_kernel (extra_arguments = args )
163165 except Exception as e : # pragma: no cover
164- raise Exception (
166+ raise NotebookKernelError (
165167 "Failure with args: {0}\n and error:\n {1}" .format (args , str (e ))) from e
166168
167169 if platform .system () == 'Darwin' :
@@ -313,14 +315,15 @@ def get_cell_code(cell):
313315 except AttributeError : # pragma: no cover
314316 return iscell , cell .input
315317
316- def run_cell (self , index_cell , cell , clean_function = None ):
318+ def run_cell (self , index_cell , cell , clean_function = None , max_nbissue = 15 ):
317319 '''
318320 Runs a notebook cell and update the output of that cell inplace.
319321
320- @param index_cell index of the cell
321- @param cell cell to execute
322- @param clean_function cleaning function to apply to the code before running it
323- @return output of the cell
322+ :param index_cell: index of the cell
323+ :param cell: cell to execute
324+ :param clean_function: cleaning function to apply to the code before running it
325+ :param max_nbissue: number of times an issue can be raised before stopping
326+ :return: output of the cell
324327 '''
325328 if self .detailed_log :
326329 self .detailed_log ("[run_cell] index_cell={0} clean_function={1}" .format (
@@ -361,8 +364,8 @@ def run_cell(self, index_cell, cell, clean_function=None):
361364 tr = [ansi_escape .sub ('' , _ )
362365 for _ in reply ['content' ]['traceback' ]]
363366 except KeyError : # pragma: no cover
364- tr = ["No traceback, available keys in reply['content']" ] + \
365- list (reply ['content' ])
367+ tr = ( ["No traceback, available keys in reply['content']" ] +
368+ list (reply ['content' ]) )
366369 traceback_text = '\n ' .join (tr )
367370 self .fLOG ("[nberror]\n " , traceback_text )
368371 if self .detailed_log :
@@ -374,19 +377,25 @@ def run_cell(self, index_cell, cell, clean_function=None):
374377
375378 outs = list ()
376379 nbissue = 0
380+ statuses = [status ]
377381 while True :
378382 try :
379383 msg = self .kc .get_iopub_msg (timeout = 1 )
380384 if msg ['msg_type' ] == 'status' :
381385 if msg ['content' ]['execution_state' ] == 'idle' :
386+ status = 'ok'
387+ statuses .append (status )
382388 break
383- except Empty : # pragma: no cover
384- # execution state should return to idle before the queue becomes empty,
389+ statuses .append (status )
390+ except Empty as e : # pragma: no cover
391+ # execution state should return to idle before
392+ # the queue becomes empty,
385393 # if it doesn't, something bad has happened
386394 status = "error"
395+ statuses .append (status )
387396 reason = "exception Empty was raised"
388397 nbissue += 1
389- if nbissue > 10 :
398+ if nbissue > max_nbissue :
390399 # the notebook is empty
391400 return ""
392401 else :
@@ -487,12 +496,17 @@ def reply2string(reply):
487496 scode = [code ]
488497 else :
489498 scode = ""
490- mes = "FILENAME\n {10}:1:1\n {7}\n CELL status={8}, reason={9} -- {4} length={5} -- {6}:\n -----------------\n {0}" + \
491- "\n -----------------\n TRACE:\n {1}\n RAW:\n {2}REPLY:\n {3}"
499+ mes = ("FILENAME\n {10}:1:1 - cell:{11}\n {7}\n CELL status={8}, reason='{9}' -- {4} "
500+ "length={5} -- {6}:\n -----------------\n "
501+ "content={12}\n msg_type: {13} nbissue={14}"
502+ "\n statuses={15}"
503+ "\n -----------------\n {0}"
504+ "\n -----------------\n TRACE:\n {1}\n RAW:\n {2}REPLY:\n {3}" )
492505 raise NotebookError (mes .format (
493- code , traceback_text , sraw , sreply , index_cell , len (
494- code ), scode , self .comment , status , reason ,
495- self ._filename ))
506+ code , traceback_text , sraw , sreply , index_cell , # 0-4
507+ len (code ), scode , self .comment , status , reason , # 5-9
508+ self ._filename , index_cell , content , msg_type , nbissue , # 10-14
509+ statuses )) # 15
496510 if self .detailed_log :
497511 self .detailed_log ('[run_cell] status={0}' .format (status ))
498512 return outs
@@ -916,9 +930,10 @@ def run_notebook(self, skip_exceptions=False, progress_callback=None,
916930 @param additional_path additional paths (as a list or None if none)
917931 @param valid if not None, valid is a function which returns whether
918932 or not the cell should be executed or not, if the function
919- returns None, the execution of the notebooks and skip the execution
920- of the other cells
921- @param clean_function function which cleans a cell's code before executing it (None for None)
933+ returns None, the execution of the notebooks and skip
934+ the execution of the other cells
935+ @param clean_function function which cleans a cell's code before executing
936+ it (None for None)
922937 @return dictionary with statistics
923938
924939 The function adds the local variable ``theNotebook`` with
0 commit comments