Index: Lib/_pyio.py =================================================================== --- Lib/_pyio.py (revision 71243) +++ Lib/_pyio.py (working copy) @@ -319,16 +319,11 @@ __closed = False def close(self) -> None: - """Flush and close the IO object. + """Close the IO 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.__closed = True + self.__closed = True def __del__(self) -> None: """Destructor. Calls close().""" Index: Lib/test/test_io.py =================================================================== --- Lib/test/test_io.py (revision 71243) +++ Lib/test/test_io.py (working copy) @@ -397,13 +397,10 @@ def close(self): record.append(2) super().close() - def flush(self): - record.append(3) - super().flush() f = MyFileIO(support.TESTFN, "wb") f.write(b"xxx") del f - self.assertEqual(record, [1, 2, 3]) + self.assertEqual(record, [1, 2]) f = open(support.TESTFN, "rb") self.assertEqual(f.read(), b"xxx") @@ -417,7 +414,6 @@ # function, not by __del__) self.on_del = 1 self.on_close = 2 - self.on_flush = 3 def __del__(self): record.append(self.on_del) try: @@ -429,12 +425,9 @@ def close(self): record.append(self.on_close) super().close() - def flush(self): - record.append(self.on_flush) - super().flush() f = MyIO() del f - self.assertEqual(record, [1, 2, 3]) + self.assertEqual(record, [1, 2]) def test_IOBase_destructor(self): self._check_base_destructor(self.IOBase) Index: Modules/_io/iobase.c =================================================================== --- Modules/_io/iobase.c (revision 71243) +++ Modules/_io/iobase.c (working copy) @@ -130,7 +130,7 @@ } PyDoc_STRVAR(IOBase_close_doc, - "Flush and close the IO object.\n" + "Close the IO object.\n" "\n" "This method has no effect if the file is already closed.\n"); @@ -169,27 +169,16 @@ } /* XXX: IOBase thinks it has to maintain its own internal state in - `__IOBase_closed` and call flush() by itself, but it is redundant with - whatever behaviour a non-trivial derived class will implement. */ + `__IOBase_closed` but it is redundant with whatever behaviour a non-trivial + derived class will implement. */ static PyObject * IOBase_close(PyObject *self, PyObject *args) { - PyObject *res; - if (IS_CLOSED(self)) Py_RETURN_NONE; - 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; - } - Py_XDECREF(res); Py_RETURN_NONE; }