Commit 550c5086 authored by Christian Heimes's avatar Christian Heimes

Fixed 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.
Approved by Barry
parent e0a7105a
......@@ -214,7 +214,9 @@ I/O Base Classes
.. method:: close()
Flush and close this stream. This method has no effect if the file is
already closed.
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
......
......@@ -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,
......
......@@ -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.
......
......@@ -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},
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment