Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 64559) +++ Python/ceval.c (working copy) @@ -1617,9 +1617,11 @@ "lost sys.stdout"); } if (w != NULL) { + Py_INCREF(w); err = PyFile_WriteString("\n", w); if (err == 0) PyFile_SoftSpace(w, 0); + Py_DECREF(w); } Py_XDECREF(stream); stream = NULL; Index: Lib/test/test_file.py =================================================================== --- Lib/test/test_file.py (revision 64559) +++ Lib/test/test_file.py (working copy) @@ -503,13 +503,32 @@ self._test_close_open_io(io_func) +class StdoutTests(unittest.TestCase): + def test_move_stdout_on_write(self): + # Issue 3242: sys.stdout can be replaced (and freed) during a + # print statement; prevent a segfault in this case + save_stdout = sys.stdout + + class File: + def write(self, data): + if '\n' in data: + sys.stdout = save_stdout + def flush(self): + + try: + sys.stdout = File() + print "some text" + finally: + sys.stdout = save_stdout + + def test_main(): # Historically, these tests have been sloppy about removing TESTFN. # So get rid of it no matter what. try: run_unittest(AutoFileTests, OtherFileTests, FileSubclassTests, - FileThreadingTests) + FileThreadingTests, StdoutTests) finally: if os.path.exists(TESTFN): os.unlink(TESTFN)