summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-09-30 12:46:53 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-09-30 12:46:53 (GMT)
commita59018c7ab905584ed94d35b2cf93067e116f8f2 (patch)
tree54e4c8b0856ea4c7fa1a736aea26692be37e83fe
parentb5102e3550a589084bf33fae15bf131f47d51b0b (diff)
downloadcpython-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.
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/fileobject.c28
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;