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.
........
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index fb651a7..07fe0a1 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -440,11 +440,7 @@
     res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
     ENTER_BUFFERED(self)
     if (res == NULL) {
-        /* If flush() fails, just give up */
-        if (PyErr_ExceptionMatches(PyExc_IOError))
-            PyErr_Clear();
-        else
-            goto end;
+        goto end;
     }
     Py_XDECREF(res);
 
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index 1482d82..4e78cd5 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -169,6 +169,7 @@
 static PyObject *
 bytesio_flush(bytesio *self)
 {
+    CHECK_CLOSED(self);
     Py_RETURN_NONE;
 }
 
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 271a41e..2d664ab 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -183,11 +183,7 @@
     res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
     PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
     if (res == NULL) {
-        /* If flush() fails, just give up */
-        if (PyErr_ExceptionMatches(PyExc_IOError))
-            PyErr_Clear();
-        else
-            return NULL;
+        return NULL;
     }
     Py_XDECREF(res);
     Py_RETURN_NONE;
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 89d922c..b039c2f 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -2398,16 +2398,30 @@
 textiowrapper_close(textio *self, PyObject *args)
 {
     PyObject *res;
+    int r;
     CHECK_INITIALIZED(self);
-    res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
-    if (res == NULL) {
-        /* If flush() fails, just give up */
-        PyErr_Clear();
-    }
-    else
-        Py_DECREF(res);
 
-    return PyObject_CallMethod(self->buffer, "close", NULL);
+    res = textiowrapper_closed_get(self, NULL);
+    if (res == NULL)
+        return NULL;
+    r = PyObject_IsTrue(res);
+    Py_DECREF(res);
+    if (r < 0)
+        return NULL;
+    
+    if (r > 0) {
+        Py_RETURN_NONE; /* stream already closed */
+    }
+    else {
+        res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+        if (res == NULL) {
+            return NULL;
+        }
+        else
+            Py_DECREF(res);
+
+        return PyObject_CallMethod(self->buffer, "close", NULL);
+    }
 }
 
 static PyObject *