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
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
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;