changeset: 98435:6347b154dd67 branch: 3.4 parent: 98412:01c79072d671 user: Serhiy Storchaka date: Wed Sep 30 15:46:53 2015 +0300 files: Misc/NEWS Objects/fileobject.c description: Issue #25182: The stdprinter (used as sys.stderr before the io module is imported at startup) now uses the backslashreplace error handler. diff -r 01c79072d671 -r 6347b154dd67 Misc/NEWS --- a/Misc/NEWS Tue Sep 29 23:52:09 2015 +0300 +++ b/Misc/NEWS Wed Sep 30 15:46:53 2015 +0300 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25182: The stdprinter (used as sys.stderr before the io module is + imported at startup) now uses the backslashreplace error handler. + - Issue #24891: Fix a race condition at Python startup if the file descriptor of stdin (0), stdout (1) or stderr (2) is closed while Python is creating sys.stdin, sys.stdout and sys.stderr objects. These attributes are now set diff -r 01c79072d671 -r 6347b154dd67 Objects/fileobject.c --- a/Objects/fileobject.c Tue Sep 29 23:52:09 2015 +0300 +++ b/Objects/fileobject.c Wed Sep 30 15:46:53 2015 +0300 @@ -372,8 +372,11 @@ static PyObject * stdprinter_write(PyStdPrinter_Object *self, PyObject *args) { - char *c; + PyObject *unicode; + PyObject *bytes = NULL; + char *str; Py_ssize_t n; + int _errno; if (self->fd < 0) { /* fd might be invalid on Windows @@ -383,24 +386,37 @@ Py_RETURN_NONE; } - if (!PyArg_ParseTuple(args, "s", &c)) { + if (!PyArg_ParseTuple(args, "U", &unicode)) return NULL; + + /* encode Unicode to UTF-8 */ + str = PyUnicode_AsUTF8AndSize(unicode, &n); + if (str == NULL) { + PyErr_Clear(); + bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace"); + if (bytes == NULL) + return NULL; + if (PyBytes_AsStringAndSize(bytes, &str, &n) < 0) { + Py_DECREF(bytes); + return NULL; + } } - n = strlen(c); Py_BEGIN_ALLOW_THREADS errno = 0; #ifdef MS_WINDOWS if (n > INT_MAX) n = INT_MAX; - n = write(self->fd, c, (int)n); + n = write(self->fd, str, (int)n); #else - n = write(self->fd, c, n); + n = write(self->fd, str, n); #endif + _errno = errno; Py_END_ALLOW_THREADS + Py_XDECREF(bytes); if (n < 0) { - if (errno == EAGAIN) + if (_errno == EAGAIN) Py_RETURN_NONE; PyErr_SetFromErrno(PyExc_IOError); return NULL;