diff --git a/src/MySQLdb/cursors.py b/src/MySQLdb/cursors.py index 03fc2386..2f781f70 100644 --- a/src/MySQLdb/cursors.py +++ b/src/MySQLdb/cursors.py @@ -8,7 +8,6 @@ from ._exceptions import ProgrammingError - #: Regular expression for ``Cursor.executemany```. #: executemany only supports simple bulk insert. #: You can use it to load large dataset. @@ -329,7 +328,13 @@ def _fetch_row(self, size=1): return self._result.fetch_row(size, self._fetch_type) def __iter__(self): - return iter(self.fetchone, None) + return self + + def __next__(self): + row = self.fetchone() + if row is None: + raise StopIteration + return row def __getattr__(self, name): # DB-API 2.0 optional extension says these errors can be accessed @@ -419,11 +424,6 @@ def scroll(self, value, mode="relative"): raise IndexError("out of range") self.rownumber = r - def __iter__(self): - self._check_executed() - result = self.rownumber and self._rows[self.rownumber :] or self._rows - return iter(result) - class CursorUseResultMixIn: """This is a MixIn class which causes the result set to be stored @@ -464,17 +464,6 @@ def fetchall(self): self.rownumber = self.rownumber + len(r) return r - def __iter__(self): - return self - - def next(self): - row = self.fetchone() - if row is None: - raise StopIteration - return row - - __next__ = next - class CursorTupleRowsMixIn: """This is a MixIn class that causes all rows to be returned as tuples, diff --git a/tests/test_cursor.py b/tests/test_cursor.py index abb84cfb..65d9c04e 100644 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -284,3 +284,27 @@ def test_sscursor_warning_count(): rows = cursor.fetchmany(2) assert len(rows) == 1 assert cursor.warning_count == 1 + + +@pytest.mark.parametrize("Cursor", [MySQLdb.cursors.Cursor, MySQLdb.cursors.SSCursor]) +def test_cursor_is_iterator(Cursor): + conn = connect() + cursor = conn.cursor(Cursor) + + cursor.execute("DROP TABLE IF EXISTS test_cursor_is_iterator") + cursor.execute( + "CREATE TABLE test_cursor_is_iterator (id INT PRIMARY KEY, name VARCHAR(20))" + ) + _tables.append("test_cursor_is_iterator") + cursor.executemany( + "INSERT INTO test_cursor_is_iterator (id, name) VALUES (%s, %s)", + [(1, "a"), (2, "b"), (3, "c")], + ) + + cursor.execute("SELECT name FROM test_cursor_is_iterator ORDER BY id") + assert iter(cursor) is cursor + assert next(cursor) == ("a",) + assert next(cursor) == ("b",) + assert next(cursor) == ("c",) + with pytest.raises(StopIteration): + next(cursor)