Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (revision 82643) +++ Python/sysmodule.c (working copy) @@ -74,6 +74,9 @@ PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; PyObject *builtins = PyDict_GetItemString(modules, "builtins"); + PyObject *encoded, *escaped_str, *repr_str, *stdout_encoding, *args; + char *stdout_encoding_str; + PyObject *buffer, *writer, *result; if (builtins == NULL) { PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); @@ -94,8 +97,71 @@ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; } - if (PyFile_WriteObject(o, outf, 0) != 0) - return NULL; + if (PyFile_WriteObject(o, outf, 0) != 0) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + /* if the encoding used by sys.stdout is not able to encode + the string, a UnicodeEncodeError will be raised. + In this case encode the string using 'backslashreplace', + check for sys.stdout.buffer and try to write it there, + or decode it again and send it to PyFile_WriteObject(). */ + stdout_encoding = PyObject_GetAttrString(outf, "encoding"); + if (stdout_encoding == NULL) + return NULL; /* with no encoding just reraise the error */ + stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); + if (stdout_encoding_str == NULL) + return NULL; + PyErr_Clear(); + repr_str = PyObject_Repr(o); + if (repr_str == NULL) { + Py_DECREF(stdout_encoding); + return NULL; + } + encoded = PyUnicode_AsEncodedString(repr_str, + stdout_encoding_str, + "backslashreplace"); + Py_DECREF(repr_str); + if (encoded == NULL) + return NULL; + buffer = PyObject_GetAttrString(outf, "buffer"); + if (buffer) { + Py_DECREF(stdout_encoding); + writer = PyObject_GetAttrString(buffer, "write"); + Py_DECREF(buffer); + if (writer == NULL) { + Py_DECREF(encoded); + return NULL; + } + args = PyTuple_Pack(1, encoded); + if (args == NULL) { + Py_DECREF(encoded); + Py_DECREF(writer); + return NULL; + } + result = PyEval_CallObject(writer, args); + Py_DECREF(args); + Py_DECREF(encoded); + Py_DECREF(writer); + if (result == NULL) + return NULL; + Py_DECREF(result); + } + else { + escaped_str = PyUnicode_FromEncodedObject(encoded, + stdout_encoding_str, + "backslashreplace"); + Py_DECREF(encoded); + Py_DECREF(stdout_encoding); + if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) { + Py_DECREF(escaped_str); + return NULL; + } + Py_DECREF(escaped_str); + } + } + else { + return NULL; + } + } if (PyFile_WriteString("\n", outf) != 0) return NULL; if (PyObject_SetAttrString(builtins, "_", o) != 0)