|
39 | 39 |
|
40 | 40 | _script_exporter = None
|
41 | 41 |
|
| 42 | +# workaround nbformat bug: |
| 43 | +# nbformat save logic will mutate the notebook if it does not |
| 44 | +# have cells ids, so if we sign the notebook, |
| 45 | +# the signature of the saved notebook is changed. |
| 46 | +# we thus need to add cell ids to the notebook before signing. |
| 47 | +try: |
| 48 | + from nbformat.validator import normalize |
| 49 | +except ImportError: |
| 50 | + from nbformat.corpus.words import generate_corpus_id |
| 51 | + from copy import deepcopy |
| 52 | + |
| 53 | + def normalize(nbdict, version, version_minor): |
| 54 | + nbdict = depcopy(nbdict) |
| 55 | + |
| 56 | + if version >= 4 and version_minor >= 5: |
| 57 | + # if we support cell ids ensure default ids are provided |
| 58 | + for cell in nbdict["cells"]: |
| 59 | + if "id" not in cell: |
| 60 | + changes += 1 |
| 61 | + # Generate cell ids if any are missing |
| 62 | + cell["id"] = generate_corpus_id() |
| 63 | + return nbdict |
| 64 | + |
42 | 65 |
|
43 | 66 | def _post_save_script(model, os_path, contents_manager, **kwargs):
|
44 | 67 | """convert notebooks to Python script after save with nbconvert
|
@@ -473,6 +496,8 @@ def save(self, model, path=''):
|
473 | 496 | try:
|
474 | 497 | if model['type'] == 'notebook':
|
475 | 498 | nb = nbformat.from_dict(model['content'])
|
| 499 | + |
| 500 | + nb = normalize(nb, nb.get("nbformat"), nb.get("nbformat_minor")) |
476 | 501 | self.check_and_sign(nb, path)
|
477 | 502 | self._save_notebook(os_path, nb)
|
478 | 503 | # One checkpoint should always exist for notebooks.
|
|
0 commit comments