Skip to content

Commit

Permalink
Better exception handling when bad json (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoxbro committed Jun 8, 2024
1 parent 08dea23 commit 62826a0
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ warn_unreachable = true
disallow_untyped_decorators = false

[tool.ruff]
line-length = 88
line-length = 99
fix = true

[tool.ruff.lint]
Expand Down
9 changes: 7 additions & 2 deletions src/clean_notebook/clean.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import json
import sys
import uuid
from pathlib import Path
from typing import Any, AnyStr, Iterator
Expand Down Expand Up @@ -36,7 +37,11 @@ def clean_single_notebook(
raw = f.read()

newline = _find_line_ending(raw)
nb = json.loads(raw)
try:
nb = json.loads(raw)
except json.JSONDecodeError as e:
print(f"{file}: Failed to json decode ({e})")
sys.exit(1)
set_id = _check_set_id(nb)

cleaned, sort_keys = False, False
Expand Down Expand Up @@ -114,7 +119,7 @@ def _find_line_ending(s: AnyStr) -> AnyStr:
endings = [b"\n", b"\r", b"\r\n"]
else:
msg = "Not str or bytes"
raise ValueError(msg)
raise TypeError(msg)

counter = {s.count(e): e for e in endings}
return counter[max(counter)]
Expand Down
71 changes: 71 additions & 0 deletions tests/data/dirty_bad_json.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"sys.version_info(major=3, minor=9, micro=13, releaselevel='final', serial=0)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import sys\n",
"\n",
"sys.version_info"
==== THIS IS A BAD EDIT ===
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"saved from vscode\")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Markdown"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.9.13 ('clean_notebook')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "b6343796ef4448f7e41a24425e4d6603c7973238ae27f15472679aaf07fca50e"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
11 changes: 10 additions & 1 deletion tests/test_clean_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def load_file(path: Path) -> bytes:
return file_bytes.replace(le, b"\n")


@pytest.fixture(scope="session")
@pytest.fixture()
def temp_path(tmp_path_factory: TempPathFactory) -> Iterator[Path]:
src = Path("tests/data").resolve(strict=True)
dst = tmp_path_factory.mktemp("data")
Expand Down Expand Up @@ -121,3 +121,12 @@ def test_empty_notebook(capsys: CaptureFixture[str], temp_path: Path) -> None:

captured = capsys.readouterr()
assert captured.out.strip() == f"Notebook '{dirty}' does not have any valid cells."


def test_bad_json(capsys: CaptureFixture[str], temp_path: Path) -> None:
file = temp_path / "dirty_bad_json.ipynb"
with pytest.raises(SystemExit):
clean_single_notebook(file)
captured = capsys.readouterr()
msg = f"{file}: Failed to json decode (Expecting ',' delimiter: line 23 column 1 (char 412))"
assert captured.out.strip() == msg

0 comments on commit 62826a0

Please sign in to comment.