Index: Objects/fileobject.c =================================================================== --- Objects/fileobject.c (révision 83197) +++ Objects/fileobject.c (copie de travail) @@ -1737,6 +1737,8 @@ Py_buffer pbuf; char *s; Py_ssize_t n, n2; + PyObject *encoded = NULL; + if (f->f_fp == NULL) return err_closed(); if (!f->writable) @@ -1746,14 +1748,42 @@ 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 { + PyObject *unicode = PyUnicode_FromObject(text); + if (unicode == NULL) + return NULL; + 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(unicode, encoding, errors); + Py_DECREF(unicode); + if (encoded == NULL) + return NULL; + s = PyString_AS_STRING(encoded); + n = PyString_GET_SIZE(encoded); + } + } 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) { Index: Lib/test/test_file2k.py =================================================================== --- Lib/test/test_file2k.py (révision 83197) +++ Lib/test/test_file2k.py (copie de travail) @@ -619,7 +619,26 @@ finally: sys.stdout = save_stdout + def test_unicode(self): + import subprocess + def check_message(text, encoding, expected): + code = '\n'.join(( + "import sys", + "sys.stdout.write(%r)" % text, + "sys.stdout.flush()")) + env = os.environ.copy() + env['PYTHONIOENCODING'] = encoding + process = subprocess.Popen([sys.executable, "-c", code], + stdout=subprocess.PIPE, env=env) + stdout, stderr = process.communicate() + self.assertEqual(process.returncode, 0) + self.assertEqual(stdout, expected) + + check_message(u'\u20ac\n', "iso-8859-15", "\xa4\n") + check_message(u'\u20ac\n', "utf-16-le", '\xac\x20\n\x00') + + def test_main(): # Historically, these tests have been sloppy about removing TESTFN. # So get rid of it no matter what.