From: Hynek Schlawack Date: Fri, 25 May 2012 08:27:43 +0000 (+0200) Subject: #4841: Fix FileIO constructor to honor closefd when called repeatedly X-Git-Tag: v3.3.0a4~75 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9866d96e48e884edb8d7db468c03db316503bbbc;p=python #4841: Fix FileIO constructor to honor closefd when called repeatedly Patch by Victor Stinner. --- 9866d96e48e884edb8d7db468c03db316503bbbc diff --cc Lib/test/test_io.py index 96258b4ccd,95ecd90a8e..f5bb732ad9 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@@ -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): diff --cc Modules/_io/fileio.c index df3affe1ee,c51d69798b..726d17b67e --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@@ -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)) {