Issue #23700: Iterator of NamedTemporaryFile now keeps a reference to
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 19 Mar 2015 13:23:15 +0000 (15:23 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Thu, 19 Mar 2015 13:23:15 +0000 (15:23 +0200)
NamedTemporaryFile instance.  Patch by Bohuslav Kabrda.

Lib/tempfile.py
Lib/test/test_tempfile.py
Misc/NEWS

index b6eeca3b1a286883433183ff8923143c85be247a..8352c38a0d7362d17015ac8b82159572d6cbc235 100644 (file)
@@ -426,7 +426,9 @@ class _TemporaryFileWrapper:
 
     # iter() doesn't use __getattr__ to find the __iter__ method
     def __iter__(self):
-        return iter(self.file)
+        # don't return iter(self.file), but yield from it to avoid closing
+        # file as long as it's being used as iterator, see issue #23000
+        yield from iter(self.file)
 
 
 def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
index 2e10fddae0f4658c880716d3d993720e1c942112..576cf4d4508318cd6453f6fd271d1985967cb79c 100644 (file)
@@ -707,6 +707,19 @@ class TestNamedTemporaryFile(BaseTestCase):
             # No reference cycle was created.
             self.assertIsNone(wr())
 
+    def test_iter(self):
+        # Issue #23700: getting iterator from a temporary file should keep
+        # it alive as long as it's being iterated over
+        lines = [b'spam\n', b'eggs\n', b'beans\n']
+        def make_file():
+            f = tempfile.NamedTemporaryFile(mode='w+b')
+            f.write(b''.join(lines))
+            f.seek(0)
+            return f
+        for i, l in enumerate(make_file()):
+            self.assertEqual(l, lines[i])
+        self.assertEqual(i, len(lines) - 1)
+
     def test_creates_named(self):
         # NamedTemporaryFile creates files with names
         f = tempfile.NamedTemporaryFile()
index 2ec41cd0c623ebadd51ecb48748d5d7be0d01c6e..2dc6e1c694d5ceffba8434e406b1868faa87dc69 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #23700: Iterator of NamedTemporaryFile now keeps a reference to
+  NamedTemporaryFile instance.  Patch by Bohuslav Kabrda.
+
 - Issue #22903: The fake test case created by unittest.loader when it fails
   importing a test module is now picklable.