comparison Python/pythonrun.c @ 73762:37300a1df7d7

Issue #13444: When stdout has been closed explicitly, we should not attempt to flush it at shutdown and print an error. This also adds a test for issue #5319, whose resolution introduced the issue.
author Antoine Pitrou <solipsis@pitrou.net>
date Sat, 26 Nov 2011 22:02:29 +0100
parents c4c1c8af0115 150e096095e5
children c86fb10eaf68
comparison
equal deleted inserted replaced
73760:5243752e19aa 73762:37300a1df7d7
346 extern void dump_counts(FILE*); 346 extern void dump_counts(FILE*);
347 #endif 347 #endif
348 348
349 /* Flush stdout and stderr */ 349 /* Flush stdout and stderr */
350 350
351 static int
352 file_is_closed(PyObject *fobj)
353 {
354 int r;
355 PyObject *tmp = PyObject_GetAttrString(fobj, "closed");
356 if (tmp == NULL) {
357 PyErr_Clear();
358 return 0;
359 }
360 r = PyObject_IsTrue(tmp);
361 Py_DECREF(tmp);
362 if (r < 0)
363 PyErr_Clear();
364 return r > 0;
365 }
366
351 static void 367 static void
352 flush_std_files(void) 368 flush_std_files(void)
353 { 369 {
354 PyObject *fout = PySys_GetObject("stdout"); 370 PyObject *fout = PySys_GetObject("stdout");
355 PyObject *ferr = PySys_GetObject("stderr"); 371 PyObject *ferr = PySys_GetObject("stderr");
356 PyObject *tmp; 372 PyObject *tmp;
357 _Py_IDENTIFIER(flush); 373 _Py_IDENTIFIER(flush);
358 374
359 if (fout != NULL && fout != Py_None) { 375 if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
360 tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); 376 tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
361 if (tmp == NULL) 377 if (tmp == NULL)
362 PyErr_WriteUnraisable(fout); 378 PyErr_WriteUnraisable(fout);
363 else 379 else
364 Py_DECREF(tmp); 380 Py_DECREF(tmp);
365 } 381 }
366 382
367 if (ferr != NULL && ferr != Py_None) { 383 if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
368 tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); 384 tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
369 if (tmp == NULL) 385 if (tmp == NULL)
370 PyErr_Clear(); 386 PyErr_Clear();
371 else 387 else
372 Py_DECREF(tmp); 388 Py_DECREF(tmp);