# HG changeset patch # Parent 99302634d7567845850a7b1830cfb8f0733583e9 diff -r 99302634d756 Lib/_pyio.py --- a/Lib/_pyio.py Sat Feb 14 01:39:17 2015 +0200 +++ b/Lib/_pyio.py Sat Feb 14 02:51:51 2015 +0000 @@ -368,16 +368,17 @@ self.__closed = True def __del__(self): - """Destructor. Calls close().""" + """Destructor. Calls flush().""" # The try/except block is in case this is called at program # exit time, when it's possible that globals have already been - # deleted, and then the close() call might fail. Since + # deleted, and then the flush() call might fail. Since # there's nothing we can do about such failures and they annoy # the end users, we suppress the traceback. - try: - self.close() - except: - pass + if not self.__closed: + try: + self.flush() + except: + pass ### Inquiries ### diff -r 99302634d756 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Sat Feb 14 01:39:17 2015 +0200 +++ b/Modules/_io/fileio.c Sat Feb 14 02:51:51 2015 +0000 @@ -479,6 +479,36 @@ } static void +fileio_finalize(PyObject *self) +{ + PyObject *exc; + PyObject *val; + PyObject *tb; + + PyErr_Fetch(&exc, &val, &tb); + if (((fileio *)self)->fd >= 0) { + PyObject *res; + + /* Signal close() that it was called as part of the object + finalization process. */ + if (PyObject_SetAttrString(self, "_finalizing", Py_True) < 0) { + PyErr_Clear(); + } + res = PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL); + /* Silencing I/O errors is bad, but printing spurious tracebacks is + equally as bad, and potentially more frequent (because of + shutdown issues). */ + if (res == NULL) { + PyErr_Clear(); + } + else { + Py_DECREF(res); + } + } + PyErr_Restore(exc, val, tb); +} + +static void fileio_dealloc(fileio *self) { self->finalizing = 1; @@ -1292,5 +1322,5 @@ 0, /* tp_weaklist */ 0, /* tp_del */ 0, /* tp_version_tag */ - 0, /* tp_finalize */ + fileio_finalize, /* tp_finalize */ }; diff -r 99302634d756 Modules/_io/iobase.c --- a/Modules/_io/iobase.c Sat Feb 14 01:39:17 2015 +0200 +++ b/Modules/_io/iobase.c Sat Feb 14 02:51:51 2015 +0000 @@ -210,7 +210,6 @@ PyObject *res; PyObject *error_type, *error_value, *error_traceback; int closed; - _Py_IDENTIFIER(_finalizing); /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); @@ -229,11 +228,7 @@ PyErr_Clear(); } if (closed == 0) { - /* Signal close() that it was called as part of the object - finalization process. */ - if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) - PyErr_Clear(); - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, + res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); /* Silencing I/O errors is bad, but printing spurious tracebacks is equally as bad, and potentially more frequent (because of