Issue #4947: The write() method of sys.stdout and sys.stderr uses their
encoding and errors attributes instead of using utf-8 in strict mode, to get
the same behaviour than the print statement.
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index d83c054..b7de6a1 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -1735,8 +1735,10 @@
file_write(PyFileObject *f, PyObject *args)
{
Py_buffer pbuf;
- char *s;
+ const char *s;
Py_ssize_t n, n2;
+ PyObject *encoded = NULL;
+
if (f->f_fp == NULL)
return err_closed();
if (!f->writable)
@@ -1746,14 +1748,41 @@
return NULL;
s = pbuf.buf;
n = pbuf.len;
- } else
- if (!PyArg_ParseTuple(args, "t#", &s, &n))
- return NULL;
+ }
+ else {
+ const char *encoding, *errors;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, "O", &text))
+ return NULL;
+
+ if (PyString_Check(text)) {
+ s = PyString_AS_STRING(text);
+ n = PyString_GET_SIZE(text);
+ } else if (PyUnicode_Check(text)) {
+ if (f->f_encoding != Py_None)
+ encoding = PyString_AS_STRING(f->f_encoding);
+ else
+ encoding = PyUnicode_GetDefaultEncoding();
+ if (f->f_errors != Py_None)
+ errors = PyString_AS_STRING(f->f_errors);
+ else
+ errors = "strict";
+ encoded = PyUnicode_AsEncodedString(text, encoding, errors);
+ if (encoded == NULL)
+ return NULL;
+ s = PyString_AS_STRING(encoded);
+ n = PyString_GET_SIZE(encoded);
+ } else {
+ if (PyObject_AsCharBuffer(text, &s, &n))
+ return NULL;
+ }
+ }
f->f_softspace = 0;
FILE_BEGIN_ALLOW_THREADS(f)
errno = 0;
n2 = fwrite(s, 1, n, f->f_fp);
FILE_END_ALLOW_THREADS(f)
+ Py_XDECREF(encoded);
if (f->f_binary)
PyBuffer_Release(&pbuf);
if (n2 != n) {