cpython: dcf25060cae8 (original) (raw)
Mercurial > cpython
changeset 95184:dcf25060cae8 2.7
Issue #21802: The reader in BufferedRWPair now is closed even when closing writer failed in BufferedRWPair.close(). [#21802]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Tue, 24 Mar 2015 23:23:42 +0200 |
parents | 1c19778123a3 |
children | 9f4d2bdced9c |
files | Lib/_pyio.py Lib/test/test_io.py Misc/NEWS Modules/_io/bufferedio.c |
diffstat | 4 files changed, 69 insertions(+), 6 deletions(-)[+] [-] Lib/_pyio.py 6 Lib/test/test_io.py 45 Misc/NEWS 3 Modules/_io/bufferedio.c 21 |
line wrap: on
line diff
--- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1216,8 +1216,10 @@ class BufferedRWPair(BufferedIOBase): return self.writer.flush() def close(self):
self.writer.close()[](#l1.7)
self.reader.close()[](#l1.8)
try:[](#l1.9)
self.writer.close()[](#l1.10)
finally:[](#l1.11)
self.reader.close()[](#l1.12)
def isatty(self): return self.reader.isatty() or self.writer.isatty()
--- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1495,6 +1495,51 @@ class BufferedRWPairTest(unittest.TestCa pair.close() self.assertTrue(pair.closed)
- def test_reader_close_error_on_close(self):
def reader_close():[](#l2.8)
reader_non_existing[](#l2.9)
reader = self.MockRawIO()[](#l2.10)
reader.close = reader_close[](#l2.11)
writer = self.MockRawIO()[](#l2.12)
pair = self.tp(reader, writer)[](#l2.13)
with self.assertRaises(NameError) as err:[](#l2.14)
pair.close()[](#l2.15)
self.assertIn('reader_non_existing', str(err.exception))[](#l2.16)
self.assertTrue(pair.closed)[](#l2.17)
self.assertFalse(reader.closed)[](#l2.18)
self.assertTrue(writer.closed)[](#l2.19)
- def test_writer_close_error_on_close(self):
def writer_close():[](#l2.22)
writer_non_existing[](#l2.23)
reader = self.MockRawIO()[](#l2.24)
writer = self.MockRawIO()[](#l2.25)
writer.close = writer_close[](#l2.26)
pair = self.tp(reader, writer)[](#l2.27)
with self.assertRaises(NameError) as err:[](#l2.28)
pair.close()[](#l2.29)
self.assertIn('writer_non_existing', str(err.exception))[](#l2.30)
self.assertFalse(pair.closed)[](#l2.31)
self.assertTrue(reader.closed)[](#l2.32)
self.assertFalse(writer.closed)[](#l2.33)
- def test_reader_writer_close_error_on_close(self):
def reader_close():[](#l2.36)
reader_non_existing[](#l2.37)
def writer_close():[](#l2.38)
writer_non_existing[](#l2.39)
reader = self.MockRawIO()[](#l2.40)
reader.close = reader_close[](#l2.41)
writer = self.MockRawIO()[](#l2.42)
writer.close = writer_close[](#l2.43)
pair = self.tp(reader, writer)[](#l2.44)
with self.assertRaises(NameError) as err:[](#l2.45)
pair.close()[](#l2.46)
self.assertIn('reader_non_existing', str(err.exception))[](#l2.47)
self.assertFalse(pair.closed)[](#l2.48)
self.assertFalse(reader.closed)[](#l2.49)
self.assertFalse(writer.closed)[](#l2.50)
+ def test_isatty(self): class SelectableIsAtty(MockRawIO): def init(self, isatty):
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -21,6 +21,9 @@ Core and Builtins Library ------- +- Issue #21802: The reader in BufferedRWPair now is closed even when closing
- Issue #23671: string.Template now allows to specify the "self" parameter as keyword argument. string.Formatter now allows to specify the "self" and the "format_string" parameters as keyword arguments.
--- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -2200,12 +2200,25 @@ bufferedrwpair_writable(rwpair *self, Py static PyObject * bufferedrwpair_close(rwpair *self, PyObject *args) {
- PyObject *exc = NULL, *val, *tb; PyObject *ret = _forward_call(self->writer, "close", args); if (ret == NULL)
PyErr_Fetch(&exc, &val, &tb);[](#l4.14)
- else
Py_DECREF(ret);[](#l4.16)
- ret = _forward_call(self->reader, "close", args);
- if (exc != NULL) {
if (ret != NULL) {[](#l4.19)
Py_CLEAR(ret);[](#l4.20)
PyErr_Restore(exc, val, tb);[](#l4.21)
}[](#l4.22)
else {[](#l4.23)
Py_DECREF(exc);[](#l4.24)
Py_XDECREF(val);[](#l4.25)
Py_XDECREF(tb);[](#l4.26)
}[](#l4.27)
- }
- return ret;