From a59018c7ab905584ed94d35b2cf93067e116f8f2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 30 Sep 2015 15:46:53 +0300 Subject: Issue #25182: The stdprinter (used as sys.stderr before the io module is imported at startup) now uses the backslashreplace error handler. --- Misc/NEWS | 3 +++ Objects/fileobject.c | 28 ++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 3d5dfa9..c3068c4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: tba 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 --git a/Objects/fileobject.c b/Objects/fileobject.c index 596f909..403d718 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -372,8 +372,11 @@ PyFile_NewStdPrinter(int fd) 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 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) 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; -- cgit v0.12