Worksheet.iter_rows() with empty sheet: TypeError: 'Worksheet' object is not an iterator
The method Worksheet.iter_rows()
is documented as returning a generator.
In my code, I call next()
on this returned value which should work if the returned value is a generator (or iterator).
However, when the worksheet is empty, a tuple is returned. See attached patch and test for fix.
diff -r 153497a0dc2b openpyxl/worksheet/tests/test_worksheet.py
--- a/openpyxl/worksheet/tests/test_worksheet.py Wed Jun 24 19:10:27 2020 +0200
+++ b/openpyxl/worksheet/tests/test_worksheet.py Tue Jun 30 13:13:13 2020 -0700
@@ -3,6 +3,7 @@
# test imports
import pytest
+import collections.abc
from itertools import islice
# package imports
@@ -87,6 +88,12 @@
for row, coord in zip(rows, expected):
assert tuple(c.coordinate for c in row) == coord
+ def test_iter_rows_is_iterator(self, Worksheet):
+ ws = Worksheet(Workbook())
+ it = ws.iter_rows()
+ assert isinstance(it, collections.abc.Iterator)
+ with pytest.raises(StopIteration):
+ next(it)
def test_cell_alternate_coordinates(self, Worksheet):
ws = Worksheet(Workbook())
@@ -208,7 +215,7 @@
def test_no_rows(self, Worksheet):
ws = Worksheet(Workbook())
- assert ws.rows == ()
+ assert tuple(ws.rows) == ()
def test_no_cols(self, Worksheet):
diff -r 153497a0dc2b openpyxl/worksheet/worksheet.py
--- a/openpyxl/worksheet/worksheet.py Wed Jun 24 19:10:27 2020 +0200
+++ b/openpyxl/worksheet/worksheet.py Tue Jun 30 13:13:13 2020 -0700
@@ -429,15 +429,12 @@
:rtype: generator
"""
- if self._current_row == 0 and not any([min_col, min_row, max_col, max_row ]):
- return ()
-
- min_col = min_col or 1
- min_row = min_row or 1
- max_col = max_col or self.max_column
- max_row = max_row or self.max_row
-
- return self._cells_by_row(min_col, min_row, max_col, max_row, values_only)
+ if self._current_row != 0 or any([min_col, min_row, max_col, max_row]):
+ min_col = min_col or 1
+ min_row = min_row or 1
+ max_col = max_col or self.max_column
+ max_row = max_row or self.max_row
+ yield from self._cells_by_row(min_col, min_row, max_col, max_row, values_only)