diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-09-30 12:46:53 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-09-30 12:46:53 (GMT) |
commit | a59018c7ab905584ed94d35b2cf93067e116f8f2 (patch) | |
tree | 54e4c8b0856ea4c7fa1a736aea26692be37e83fe /Objects/fileobject.c | |
parent | b5102e3550a589084bf33fae15bf131f47d51b0b (diff) | |
download | cpython-a59018c7ab905584ed94d35b2cf93067e116f8f2.zip cpython-a59018c7ab905584ed94d35b2cf93067e116f8f2.tar.gz cpython-a59018c7ab905584ed94d35b2cf93067e116f8f2.tar.bz2 |
Issue #25182: The stdprinter (used as sys.stderr before the io module is
imported at startup) now uses the backslashreplace error handler.
Diffstat (limited to 'Objects/fileobject.c')
-rw-r--r-- | Objects/fileobject.c | 28 |
1 files changed, 22 insertions, 6 deletions
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; |