From 75b3ca8b9e298e935ed194766cd6309d5e31f3d6 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 25 May 2026 14:11:19 +0200 Subject: [PATCH] fix(normalizer): don't coerce boolean cells to 1/0 Add bool guard before the int branch in _cell_to_str so True/False cells are preserved as "True"/"False" instead of "1"/"0". Add two regression tests covering the fix and missing-sheet error. Co-Authored-By: Claude Opus 4.7 --- tools/import-normalizer/ingest.py | 2 ++ tools/import-normalizer/tests/test_ingest.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/tools/import-normalizer/ingest.py b/tools/import-normalizer/ingest.py index 171a1a24..7c7c8de2 100644 --- a/tools/import-normalizer/ingest.py +++ b/tools/import-normalizer/ingest.py @@ -7,6 +7,8 @@ import openpyxl def _cell_to_str(value) -> str: if value is None: return "" + if isinstance(value, bool): # bool is a subclass of int — handle before the int branch + return str(value) if isinstance(value, datetime.datetime): return value.date().isoformat() if isinstance(value, datetime.date): diff --git a/tools/import-normalizer/tests/test_ingest.py b/tools/import-normalizer/tests/test_ingest.py index ba745c88..7cce1452 100644 --- a/tools/import-normalizer/tests/test_ingest.py +++ b/tools/import-normalizer/tests/test_ingest.py @@ -34,3 +34,13 @@ def test_build_header_map_collapses_whitespace_and_case(): def test_build_header_map_missing_required_raises(): with pytest.raises(ValueError, match="index"): ingest.build_header_map(["Box", "Ort"], {"box": "box", "ort": "location"}, required={"index"}) + +def test_read_sheet_bool_not_coerced_to_int(tmp_path): + path = _make_workbook(tmp_path, "S", [["Flag"], [True], [False]]) + rows = ingest.read_sheet(path, "S") + assert rows[1] == ["True"] and rows[2] == ["False"] # not "1"/"0" + +def test_read_sheet_missing_sheet_raises(tmp_path): + path = _make_workbook(tmp_path, "S", [["A"]]) + with pytest.raises(ValueError, match="not found"): + ingest.read_sheet(path, "Nope")