From f58256883eff38e121bcc7daf1ab91fd68e7e4a4 Mon Sep 17 00:00:00 2001 From: Ryan Duguid Date: Wed, 7 Oct 2026 23:31:19 +1100 Subject: [PATCH] Fix row iteration over empty worksheets --- src/types/sheet.rs | 6 +++++- tests/test_base.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/types/sheet.rs b/src/types/sheet.rs index dd237dd..c696c80 100644 --- a/src/types/sheet.rs +++ b/src/types/sheet.rs @@ -250,7 +250,7 @@ impl CalamineCellIterator { CalamineCellIterator { empty_row, position: 0, - start: range.start().unwrap(), + start: range.start().unwrap_or_default(), iter: unsafe { std::mem::transmute::< calamine::Rows<'_, calamine::Data>, @@ -269,6 +269,10 @@ impl CalamineCellIterator { } fn __next__(mut slf: PyRefMut<'_, Self>) -> PyResult>> { + if slf.range.is_empty() { + return Ok(None); + } + slf.position += 1; if slf.position > slf.start.0 { slf.iter diff --git a/tests/test_base.py b/tests/test_base.py index 4140983..fe8ff14 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -222,6 +222,24 @@ def test_xlsx_iter_rows(): assert data == list(reader.get_sheet_by_index(0).iter_rows()) +@pytest.mark.parametrize("filename", ["base.xlsx", "base.xls", "base.xlsb", "base.ods"]) +def test_iter_rows_empty_sheet(filename): + reader = CalamineWorkbook.from_object(PATH / filename) + sheet = reader.get_sheet_by_index(1) + + assert sheet.start is None + assert sheet.end is None + rows = sheet.iter_rows() + + assert list(rows) == [] + for _ in range(3): + with pytest.raises(StopIteration): + next(rows) + + sentinel = object() + assert next(rows, sentinel) is sentinel + + def test_nrows(): reader = CalamineWorkbook.from_object(PATH / "base.xlsx") sheet = reader.get_sheet_by_name("Sheet3")