From: Antoine Pitrou Date: Sat, 5 Nov 2011 23:38:45 +0000 (+0100) Subject: Issue #13342: input() used to ignore sys.stdin's and sys.stdout's unicode X-Git-Tag: v3.3.0a1~929 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5ee9d8a8a24333a8b96e17e338289180bbe653f0;p=thirdparty%2FPython%2Fcpython.git Issue #13342: input() used to ignore sys.stdin's and sys.stdout's unicode error handler in interactive mode (when calling into PyOS_Readline()). --- 5ee9d8a8a24333a8b96e17e338289180bbe653f0 diff --cc Lib/test/test_builtin.py index 587c1c04e92e,40c1ab4fd050..d4e293cee2a8 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@@ -10,8 -11,12 +11,12 @@@ import as import types import builtins import random -from test.support import fcmp, TESTFN, unlink, run_unittest, check_warnings +from test.support import TESTFN, unlink, run_unittest, check_warnings from operator import neg + try: + import pty + except ImportError: + pty = None class Squares: diff --cc Python/bltinmodule.c index 0c14d7e32616,9e37d21b5df5..4d960b8d1c5b --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@@ -1634,65 -1640,55 +1634,57 @@@ builtin_input(PyObject *self, PyObject /* If we're interactive, use (GNU) readline */ if (tty) { - PyObject *po; + PyObject *po = NULL; char *prompt; - char *s; - PyObject *stdin_encoding; - char *stdin_encoding_str; + char *s = NULL; + PyObject *stdin_encoding = NULL, *stdin_errors = NULL; + PyObject *stdout_encoding = NULL, *stdout_errors = NULL; + char *stdin_encoding_str, *stdin_errors_str; PyObject *result; size_t len; + _Py_IDENTIFIER(encoding); ++ _Py_IDENTIFIER(errors); - stdin_encoding = PyObject_GetAttrString(fin, "encoding"); - stdin_errors = PyObject_GetAttrString(fin, "errors"); + stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); - if (!stdin_encoding) ++ stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); + if (!stdin_encoding || !stdin_errors) /* stdin is a text stream, so it must have an encoding. */ - return NULL; + goto _readline_errors; stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); - if (stdin_encoding_str == NULL) { - Py_DECREF(stdin_encoding); - return NULL; - } + stdin_errors_str = _PyUnicode_AsString(stdin_errors); + if (!stdin_encoding_str || !stdin_errors_str) + goto _readline_errors; - tmp = PyObject_CallMethod(fout, "flush", ""); + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else Py_DECREF(tmp); if (promptarg != NULL) { + /* We have a prompt, encode it as stdout would */ + char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; - PyObject *stdout_encoding; - char *stdout_encoding_str; - stdout_encoding = PyObject_GetAttrString(fout, "encoding"); - stdout_errors = PyObject_GetAttrString(fout, "errors"); + stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); - if (stdout_encoding == NULL) { - Py_DECREF(stdin_encoding); - return NULL; - } ++ stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); + if (!stdout_encoding || !stdout_errors) + goto _readline_errors; stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); - if (stdout_encoding_str == NULL) { - Py_DECREF(stdin_encoding); - Py_DECREF(stdout_encoding); - return NULL; - } + stdout_errors_str = _PyUnicode_AsString(stdout_errors); + if (!stdout_encoding_str || !stdout_errors_str) + goto _readline_errors; stringpo = PyObject_Str(promptarg); - if (stringpo == NULL) { - Py_DECREF(stdin_encoding); - Py_DECREF(stdout_encoding); - return NULL; - } + if (stringpo == NULL) + goto _readline_errors; po = PyUnicode_AsEncodedString(stringpo, - stdout_encoding_str, NULL); - Py_DECREF(stdout_encoding); - Py_DECREF(stringpo); - if (po == NULL) { - Py_DECREF(stdin_encoding); - return NULL; - } + stdout_encoding_str, stdout_errors_str); + Py_CLEAR(stdout_encoding); + Py_CLEAR(stdout_errors); + Py_CLEAR(stringpo); + if (po == NULL) + goto _readline_errors; prompt = PyBytes_AsString(po); - if (prompt == NULL) { - Py_DECREF(stdin_encoding); - Py_DECREF(po); - return NULL; - } + if (prompt == NULL) + goto _readline_errors; } else { po = NULL;