Index: Lib/test/test_io.py =================================================================== --- Lib/test/test_io.py (Revision 67070) +++ Lib/test/test_io.py (Arbeitskopie) @@ -9,6 +9,8 @@ import unittest from itertools import chain, cycle from test import support +import warnings +import gc import codecs import io # The module under test @@ -1237,20 +1239,55 @@ else: self.assert_(issubclass(obj, io.IOBase)) + +class CloseFDTest(unittest.TestCase): + def setUp(sel): + with io.open(support.TESTFN, "w") as f: + f.write("line1\n") + f.write("line2\n") + def test_fileio_warnings(self): with support.check_warnings() as w: self.assertEqual(w.warnings, []) self.assertRaises(TypeError, io.FileIO, []) self.assertEqual(w.warnings, []) - self.assertRaises(ValueError, io.FileIO, "/some/invalid/name", "rt") + self.assertRaises(ValueError, io.FileIO, "support.TESTFN", "rt") self.assertEqual(w.warnings, []) + def testReadClosed(self): + with io.open(support.TESTFN, "r") as f: + file = io.FileIO(f.fileno(), "r", closefd=False) + file.close() + self.assertRaises(ValueError, file.readline) + + def testNoClose(self): + with support.check_warnings() as w: + with io.open(support.TESTFN, "r") as f: + self.assertEqual(w.warnings, []) + file = io.FileIO(f.fileno(), "r", closefd=False) + # destructor should no raise a RuntimeWarning + # (close unclosable file) + del file + gc.collect() + self.assertEqual(w.warnings, []) + + def test_no_closefd_with_filename(self): + # can't use closefd in combination with a file name + self.assertRaises(ValueError, io.open, support.TESTFN, "r", closefd=False) + + def test_closefd_attr(self): + with io.open(support.TESTFN, "r") as f: + self.assertEqual(f.buffer.raw.closefd, True) + file = io.FileIO(f.fileno(), "r", closefd=False) + self.assertEqual(file.closefd, False) + + def test_main(): support.run_unittest(IOTest, BytesIOTest, StringIOTest, BufferedReaderTest, BufferedWriterTest, BufferedRWPairTest, BufferedRandomTest, StatefulIncrementalDecoderTest, - TextIOWrapperTest, MiscIOTest) + TextIOWrapperTest, MiscIOTest, CloseFDTest) if __name__ == "__main__": unittest.main() Index: Modules/_fileio.c =================================================================== --- Modules/_fileio.c (Revision 67070) +++ Modules/_fileio.c (Arbeitskopie) @@ -61,10 +61,7 @@ fileio_close(PyFileIOObject *self) { if (!self->closefd) { - if (PyErr_WarnEx(PyExc_RuntimeWarning, - "Trying to close unclosable fd!", 3) < 0) { - return NULL; - } + self->fd = -1; Py_RETURN_NONE; } errno = internal_close(self); @@ -821,6 +818,12 @@ } static PyObject * +get_closefd(PyFileIOObject *self, void *closure) +{ + return PyBool_FromLong((long)(self->closefd)); +} + +static PyObject * get_mode(PyFileIOObject *self, void *closure) { return PyUnicode_FromString(mode_string(self)); @@ -828,6 +831,8 @@ static PyGetSetDef fileio_getsetlist[] = { {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"closefd", (getter)get_closefd, NULL, + "True if the file descriptor will be closed"}, {"mode", (getter)get_mode, NULL, "String giving the file mode"}, {0}, };