]> granicus.if.org Git - python/commitdiff
#4841: Fix FileIO constructor to honor closefd when called repeatedly
authorHynek Schlawack <hs@ox.cx>
Fri, 25 May 2012 08:27:43 +0000 (10:27 +0200)
committerHynek Schlawack <hs@ox.cx>
Fri, 25 May 2012 08:27:43 +0000 (10:27 +0200)
Patch by Victor Stinner.

1  2 
Lib/test/test_io.py
Modules/_io/fileio.c

index 96258b4ccd7aba2001bb02c48d85f7f1619d05e7,95ecd90a8ecf8fcceb510bd767e4d1d1b656cc49..f5bb732ad9c4d8cfda466c9a7556d4667a2265fe
@@@ -634,15 -634,19 +634,28 @@@ class IOTest(unittest.TestCase)
          for obj in test:
              self.assertTrue(hasattr(obj, "__dict__"))
  
 +    def test_opener(self):
 +        with self.open(support.TESTFN, "w") as f:
 +            f.write("egg\n")
 +        fd = os.open(support.TESTFN, os.O_RDONLY)
 +        def opener(path, flags):
 +            return fd
 +        with self.open("non-existent", "r", opener=opener) as f:
 +            self.assertEqual(f.read(), "egg\n")
 +
+     def test_fileio_closefd(self):
+         # Issue #4841
+         with self.open(__file__, 'rb') as f1, \
+              self.open(__file__, 'rb') as f2:
+             fileio = self.FileIO(f1.fileno(), closefd=False)
+             # .__init__() must not close f1
+             fileio.__init__(f2.fileno(), closefd=False)
+             f1.readline()
+             # .close() must not close f2
+             fileio.close()
+             f2.readline()
  class CIOTest(IOTest):
  
      def test_IOBase_finalize(self):
index df3affe1ee2de7a7c9abc68b6c979c3ee8f29e3f,c51d69798bdbf073b0c0bf7daefcdb09a4a58ad0..726d17b67e2cdccad08959f3d8e0604d2146657f
@@@ -230,14 -227,17 +230,18 @@@ fileio_init(PyObject *oself, PyObject *
  
      assert(PyFileIO_Check(oself));
      if (self->fd >= 0) {
-         /* Have to close the existing file first. */
-         if (internal_close(self) < 0)
-             return -1;
+         if (self->closefd) {
+             /* Have to close the existing file first. */
+             if (internal_close(self) < 0)
+                 return -1;
+         }
+         else
+             self->fd = -1;
      }
  
 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:fileio",
 -                                     kwlist, &nameobj, &mode, &closefd))
 +    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|siO:fileio",
 +                                     kwlist, &nameobj, &mode, &closefd,
 +                                     &opener))
          return -1;
  
      if (PyFloat_Check(nameobj)) {