Kaydet (Commit) 01a255ad authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Merged revisions 80720 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r80720 | antoine.pitrou | 2010-05-03 18:25:33 +0200 (lun., 03 mai 2010) | 5 lines

  Issue #7865: The close() method of :mod:`io` objects should not swallow
  exceptions raised by the implicit flush().  Also ensure that calling
  close() several times is supported.  Patch by Pascal Chambon.
........
üst 2f49f4eb
......@@ -368,6 +368,9 @@ class IOBase(object):
This is not implemented for read-only and non-blocking streams.
"""
if self.__closed:
raise ValueError("flush of closed file")
#self._checkClosed()
# XXX Should this return the number of bytes written???
__closed = False
......@@ -378,10 +381,7 @@ class IOBase(object):
This method has no effect if the file is already closed.
"""
if not self.__closed:
try:
self.flush()
except IOError:
pass # If flush() fails, just give up
self.flush()
self.__closed = True
def __del__(self):
......@@ -751,10 +751,7 @@ class _BufferedIOMixin(BufferedIOBase):
def close(self):
if not self.closed:
try:
self.flush()
except IOError:
pass # If flush() fails, just give up
self.flush()
self.raw.close()
### Inquiries ###
......@@ -1087,6 +1084,8 @@ class BufferedWriter(_BufferedIOMixin):
return self.raw.truncate(pos)
def flush(self):
if self.closed:
raise ValueError("flush of closed file")
with self._write_lock:
self._flush_unlocked()
......@@ -1472,11 +1471,9 @@ class TextIOWrapper(TextIOBase):
self._telling = self._seekable
def close(self):
try:
if not self.closed:
self.flush()
except:
pass # If flush() fails, just give up
self.buffer.close()
self.buffer.close()
@property
def closed(self):
......
......@@ -313,6 +313,20 @@ class IOTest(unittest.TestCase):
file = io.open(f.fileno(), "r", closefd=False)
self.assertEqual(file.buffer.raw.closefd, False)
def test_flush_error_on_close(self):
f = io.open(test_support.TESTFN, "wb", buffering=0)
def bad_flush():
raise IOError()
f.flush = bad_flush
self.assertRaises(IOError, f.close) # exception not swallowed
def test_multi_close(self):
f = io.open(test_support.TESTFN, "wb", buffering=0)
f.close()
f.close()
f.close()
self.assertRaises(ValueError, f.flush)
class MemorySeekTestMixin:
......@@ -565,6 +579,22 @@ class BufferedWriterTest(unittest.TestCase):
finally:
test_support.unlink(test_support.TESTFN)
def test_flush_error_on_close(self):
raw = MockRawIO()
def bad_flush():
raise IOError()
raw.flush = bad_flush
b = io.BufferedWriter(raw)
self.assertRaises(IOError, b.close) # exception not swallowed
def test_multi_close(self):
raw = MockRawIO()
b = io.BufferedWriter(raw)
b.close()
b.close()
b.close()
self.assertRaises(ValueError, b.flush)
class BufferedRWPairTest(unittest.TestCase):
......@@ -1295,6 +1325,20 @@ class TextIOWrapperTest(unittest.TestCase):
decoder = io.IncrementalNewlineDecoder(decoder, translate=True)
self.check_newline_decoder_utf8(decoder)
def test_flush_error_on_close(self):
txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ascii")
def bad_flush():
raise IOError()
txt.flush = bad_flush
self.assertRaises(IOError, txt.close) # exception not swallowed
def test_multi_close(self):
txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ascii")
txt.close()
txt.close()
txt.close()
self.assertRaises(ValueError, txt.flush)
# XXX Tests for open()
......
......@@ -33,6 +33,10 @@ Core and Builtins
Library
-------
- Issue #7865: The close() method of :mod:`io` objects should not swallow
exceptions raised by the implicit flush(). Also ensure that calling
close() several times is supported. Initial patch by Pascal Chambon.
- Issue #8581: logging: removed errors raised when closing handlers twice.
- Issue #4687: Fix accuracy of garbage collection runtimes displayed with
......
......@@ -163,6 +163,7 @@ PyDoc_STRVAR(flush_doc,
static PyObject *
bytesio_flush(BytesIOObject *self)
{
CHECK_CLOSED(self);
Py_RETURN_NONE;
}
......
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