2323except ModuleNotFoundError :
2424 pass
2525
26+ nbf_v = nbformat .v4
27+
28+ def _normalize (nb ):
29+ return nbformat .validator .normalize (nb , version = 4 , version_minor = 5 )[1 ]
30+
2631
2732# noinspection PyBroadException
2833def pretty_format_python (python_txt : str , * , black_mode = None ) -> str :
@@ -69,7 +74,6 @@ def convert_py_code_to_notebook(
6974 begin_text_regexp = re .compile (r"^\s*r?((''')|(\"\"\"))\s*begin\s+text\s*$" )
7075 end_text_regexp = re .compile (r"^\s*r?((''')|(\"\"\"))\s*#\s*end\s+text\s*$" )
7176 end_code_regexp = re .compile (r"(^\s*r?'''\s*end\s+code\s*'''\s*$)|(^\s*r?\"\"\"\s*end\s+code\s*\"\"\"\s*$)" )
72- nbf_v = nbformat .v4
7377 # run a little code collecting state machine
7478 cells = []
7579 collecting_python = []
@@ -110,8 +114,10 @@ def convert_py_code_to_notebook(
110114 collecting_python .append (line )
111115 if collecting_text is not None :
112116 collecting_text .append (line )
117+ for i in range (len (cells )):
118+ cells [i ]["id" ] = f"cell{ i } "
113119 nb = nbf_v .new_notebook (cells = cells )
114- nb = nbformat . validator . normalize (nb )[ 1 ]
120+ nb = _normalize (nb )
115121 return nb
116122
117123
@@ -127,12 +133,18 @@ def prepend_code_cell_to_notebook(
127133 :param code_text: Python source code to add
128134 :return: new notebook
129135 """
130- nbf_v = nbformat .v4
131- cells = [nbf_v .new_code_cell (code_text )] + list (nb .cells )
136+ header_cell = nbf_v .new_code_cell (code_text )
137+ # set cell ids to avoid:
138+ # "MissingIDFieldWarning: Code cell is missing an id field, this will become a hard error in future nbformat versions."
139+ header_cell ["id" ] = "wvpy_header_cell"
140+ orig_cells = [c .copy () for c in nb .cells ]
141+ for i in range (len (orig_cells )):
142+ orig_cells [i ]["id" ] = f"cell{ i } "
143+ cells = [header_cell ] + orig_cells
132144 nb_out = nbf_v .new_notebook (
133145 cells = cells
134146 )
135- nb_out = nbformat . validator . normalize (nb_out )[ 1 ]
147+ nb_out = _normalize (nb_out )
136148 return nb_out
137149
138150
@@ -288,7 +300,7 @@ def render_as_html(
288300 else :
289301 raise ValueError ('{ipynb_exists}: file must end with .py or .ipynb' )
290302 # do the conversion
291- if init_code is not None :
303+ if ( init_code is not None ) and ( len ( init_code ) > 0 ) :
292304 assert isinstance (init_code , str )
293305 nb = prepend_code_cell_to_notebook (
294306 nb ,
0 commit comments