From 2c4670285122e24972d6c6630616bffe2621ceb1 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Sat, 22 Jul 2023 18:28:32 +0100 Subject: [PATCH] Catch NotJSONError in wait_and_check_if_empty() This appears to be a rare error and its cause is not clear. The working assumption is that this exception may be raised if Spyder tries to read the notebook file before it is completely saved, so we wait a while and try again. --- spyder_notebook/widgets/notebooktabwidget.py | 2 +- .../widgets/tests/test_notebooktabwidget.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/spyder_notebook/widgets/notebooktabwidget.py b/spyder_notebook/widgets/notebooktabwidget.py index 6fac05cb..c6e76400 100755 --- a/spyder_notebook/widgets/notebooktabwidget.py +++ b/spyder_notebook/widgets/notebooktabwidget.py @@ -348,7 +348,7 @@ def wait_and_check_if_empty(filename): # Try reading the file try: nb_contents = nbformat.read(filename, as_version=4) - except FileNotFoundError: + except (FileNotFoundError, nbformat.reader.NotJSONError): continue # If empty, we are done diff --git a/spyder_notebook/widgets/tests/test_notebooktabwidget.py b/spyder_notebook/widgets/tests/test_notebooktabwidget.py index 1e3190fa..506863d6 100755 --- a/spyder_notebook/widgets/tests/test_notebooktabwidget.py +++ b/spyder_notebook/widgets/tests/test_notebooktabwidget.py @@ -12,6 +12,7 @@ # Third party imports import pytest from qtpy.QtWidgets import QMessageBox +from nbformat.reader import NotJSONError # Local imports from spyder_notebook.utils.servermanager import ServerManager @@ -138,15 +139,16 @@ def test_wait_and_check_if_empty_when_not_empty(mocker, tabwidget): assert result is False -def test_wait_and_check_if_empty_with_delay(mocker, tabwidget): +@pytest.mark.parametrize('exception', [FileNotFoundError, NotJSONError]) +def test_wait_and_check_if_empty_with_delay(mocker, tabwidget, exception): """Test that .wait_and_check_if_empty() on an empty notebook tries to read - it, and when that fails because the file does not exist, it tries again to - read it. When the read succeeds the second time and the notebook turns out - to be empty, the function returns True.""" + it, and when that fails because the file does not exist or is not JSON, it + tries again to read it. When the read succeeds the second time and the + notebook turns out to be empty, the function returns True.""" contents = {'cells': []} mock_read = mocker.patch( 'spyder_notebook.widgets.notebooktabwidget.nbformat.read', - side_effect=[FileNotFoundError, contents]) + side_effect=[exception, contents]) result = tabwidget.wait_and_check_if_empty('ham.ipynb')