From: Andrej Shadura <andrewsh@debian.org>
Date: Sat Sep 29 14:16:43 2018 +0200
Subject: Catch StopIteration from raised from next()

Generators should not raise StopIteration, but return instead.
Python 3.7 enforces that.

diff --git a/scrapy/utils/iterators.py b/scrapy/utils/iterators.py
index 73857b4..dc023e9 100644
--- a/scrapy/utils/iterators.py
+++ b/scrapy/utils/iterators.py
@@ -112,19 +112,22 @@ def csviter(obj, delimiter=None, headers=None, encoding=None, quotechar=None):
     if quotechar: kwargs["quotechar"] = quotechar
     csv_r = csv.reader(lines, **kwargs)
 
-    if not headers:
-        headers = _getrow(csv_r)
-
-    while True:
-        row = _getrow(csv_r)
-        if len(row) != len(headers):
-            logger.warning("ignoring row %(csvlnum)d (length: %(csvrow)d, "
-                           "should be: %(csvheader)d)",
-                           {'csvlnum': csv_r.line_num, 'csvrow': len(row),
-                            'csvheader': len(headers)})
-            continue
-        else:
-            yield dict(zip(headers, row))
+    try:
+        if not headers:
+            headers = _getrow(csv_r)
+
+        while True:
+            row = _getrow(csv_r)
+            if len(row) != len(headers):
+                logger.warning("ignoring row %(csvlnum)d (length: %(csvrow)d, "
+                               "should be: %(csvheader)d)",
+                               {'csvlnum': csv_r.line_num, 'csvrow': len(row),
+                                'csvheader': len(headers)})
+                continue
+            else:
+                yield dict(zip(headers, row))
+    except StopIteration:
+        return
 
 
 def _body_or_str(obj, unicode=True):
