[Python-checkins] cpython (2.7): Issue #21802: The reader in BufferedRWPair now is closed even when closing

serhiy.storchaka python-checkins at python.org
Tue Mar 24 22:24:28 CET 2015


https://hg.python.org/cpython/rev/dcf25060cae8
changeset: 95184:dcf25060cae8
branch: 2.7
parent: 95177:1c19778123a3
user: Serhiy Storchaka <storchaka at gmail.com>
date: Tue Mar 24 23:23:42 2015 +0200
summary:
 Issue #21802: The reader in BufferedRWPair now is closed even when closing
writer failed in BufferedRWPair.close().
files:
 Lib/_pyio.py | 6 ++-
 Lib/test/test_io.py | 45 ++++++++++++++++++++++++++++
 Misc/NEWS | 3 +
 Modules/_io/bufferedio.c | 21 ++++++++++--
 4 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1216,8 +1216,10 @@
 return self.writer.flush()
 
 def close(self):
- self.writer.close()
- self.reader.close()
+ try:
+ self.writer.close()
+ finally:
+ self.reader.close()
 
 def isatty(self):
 return self.reader.isatty() or self.writer.isatty()
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -1495,6 +1495,51 @@
 pair.close()
 self.assertTrue(pair.closed)
 
+ def test_reader_close_error_on_close(self):
+ def reader_close():
+ reader_non_existing
+ reader = self.MockRawIO()
+ reader.close = reader_close
+ writer = self.MockRawIO()
+ pair = self.tp(reader, writer)
+ with self.assertRaises(NameError) as err:
+ pair.close()
+ self.assertIn('reader_non_existing', str(err.exception))
+ self.assertTrue(pair.closed)
+ self.assertFalse(reader.closed)
+ self.assertTrue(writer.closed)
+
+ def test_writer_close_error_on_close(self):
+ def writer_close():
+ writer_non_existing
+ reader = self.MockRawIO()
+ writer = self.MockRawIO()
+ writer.close = writer_close
+ pair = self.tp(reader, writer)
+ with self.assertRaises(NameError) as err:
+ pair.close()
+ self.assertIn('writer_non_existing', str(err.exception))
+ self.assertFalse(pair.closed)
+ self.assertTrue(reader.closed)
+ self.assertFalse(writer.closed)
+
+ def test_reader_writer_close_error_on_close(self):
+ def reader_close():
+ reader_non_existing
+ def writer_close():
+ writer_non_existing
+ reader = self.MockRawIO()
+ reader.close = reader_close
+ writer = self.MockRawIO()
+ writer.close = writer_close
+ pair = self.tp(reader, writer)
+ with self.assertRaises(NameError) as err:
+ pair.close()
+ self.assertIn('reader_non_existing', str(err.exception))
+ self.assertFalse(pair.closed)
+ self.assertFalse(reader.closed)
+ self.assertFalse(writer.closed)
+
 def test_isatty(self):
 class SelectableIsAtty(MockRawIO):
 def __init__(self, isatty):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,9 @@
 Library
 -------
 
+- Issue #21802: The reader in BufferedRWPair now is closed even when closing
+ writer failed in BufferedRWPair.close().
+
 - 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.
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -2200,12 +2200,25 @@
 static PyObject *
 bufferedrwpair_close(rwpair *self, PyObject *args)
 {
+ PyObject *exc = NULL, *val, *tb;
 PyObject *ret = _forward_call(self->writer, "close", args);
 if (ret == NULL)
- return NULL;
- Py_DECREF(ret);
-
- return _forward_call(self->reader, "close", args);
+ PyErr_Fetch(&exc, &val, &tb);
+ else
+ Py_DECREF(ret);
+ ret = _forward_call(self->reader, "close", args);
+ if (exc != NULL) {
+ if (ret != NULL) {
+ Py_CLEAR(ret);
+ PyErr_Restore(exc, val, tb);
+ }
+ else {
+ Py_DECREF(exc);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+ }
+ }
+ return ret;
 }
 
 static PyObject *
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /