]> granicus.if.org Git - python/commitdiff
Fixed issue #4233.
authorChristian Heimes <christian@cheimes.de>
Wed, 5 Nov 2008 19:30:32 +0000 (19:30 +0000)
committerChristian Heimes <christian@cheimes.de>
Wed, 5 Nov 2008 19:30:32 +0000 (19:30 +0000)
Changed semantic of _fileio.FileIO's close()  method on file objects with closefd=False. The file descriptor is still kept open but the file object behaves like a closed file. The FileIO  object also got a new readonly attribute closefd.
Approved by Barry

Doc/library/io.rst
Lib/test/test_io.py
Misc/NEWS
Modules/_fileio.c

index 543bb373c563a6001d61256d101b683571cdc36c..14f750669401bf053684f9c6149da6fc8e585edc 100644 (file)
@@ -213,8 +213,10 @@ I/O Base Classes
 
    .. method:: close()
 
-      Flush and close this stream.  This method has no effect if the file is
-      already closed.
+      Flush and close this stream. This method has no effect if the file is
+      already closed. Once the file is closed, any operation on the file 
+      (e.g. reading or writing) will raise an :exc:`IOError`. The internal
+      file descriptor isn't closed if *closefd* was False.
 
    .. attribute:: closed
 
index f28bade6c72932659bd0b5f9e497508a391eb6c9..1f0295c1d46a7b57ac0938372bbd7dd8371fed0d 100644 (file)
@@ -272,6 +272,29 @@ class IOTest(unittest.TestCase):
         self.assertRaises(ValueError, io.open, support.TESTFN, 'w',
                           closefd=False)
 
+    def testReadClosed(self):
+        with io.open(support.TESTFN, "w") as f:
+            f.write("egg\n")
+        with io.open(support.TESTFN, "r") as f:
+            file = io.open(f.fileno(), "r", closefd=False)
+            self.assertEqual(file.read(), "egg\n")
+            file.seek(0)
+            file.close()
+            self.assertRaises(ValueError, file.read)
+
+    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, "wb") as f:
+            f.write(b"egg\n")
+        with io.open(support.TESTFN, "r") as f:
+            self.assertEqual(f.buffer.raw.closefd, True)
+            file = io.open(f.fileno(), "r", closefd=False)
+            self.assertEqual(file.buffer.raw.closefd, False)
+
+
 class MemorySeekTestMixin:
 
     def testInit(self):
@@ -1237,15 +1260,6 @@ class MiscIOTest(unittest.TestCase):
             else:
                 self.assert_(issubclass(obj, io.IOBase))
 
-    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.assertEqual(w.warnings, [])
-
-
 def test_main():
     support.run_unittest(IOTest, BytesIOTest, StringIOTest,
                               BufferedReaderTest, BufferedWriterTest,
index 7de06851fc077ae2cf78a69043274f261eeb7dd1..f17e758aa3735e384053b54e04e698a4a9e57906 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,11 @@ What's New in Python 3.0 beta 5
 Core and Builtins
 -----------------
 
+- Issue #4233: Changed semantic of ``_fileio.FileIO``'s ``close()`` 
+  method on file objects with closefd=False. The file descriptor is still
+  kept open but the file object behaves like a closed file. The ``FileIO``
+  object also got a new readonly attribute ``closefd``.
+
 - Issue #3626: On cygwin, starting python with a non-existent script name
   would not display anything if the file name is only 1 character long.
 
index a946ea51284a6521775ef285e5681618b957c587..2cec2132235d68b36c8a62082cb5ce9bcd3c2fd9 100644 (file)
@@ -61,10 +61,7 @@ static PyObject *
 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);
@@ -820,6 +817,12 @@ get_closed(PyFileIOObject *self, void *closure)
        return PyBool_FromLong((long)(self->fd < 0));
 }
 
+static PyObject *
+get_closefd(PyFileIOObject *self, void *closure)
+{
+       return PyBool_FromLong((long)(self->closefd));
+}
+
 static PyObject *
 get_mode(PyFileIOObject *self, void *closure)
 {
@@ -828,6 +831,8 @@ get_mode(PyFileIOObject *self, void *closure)
 
 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},
 };