Issue #13342: input() used to ignore sys.stdin's and sys.stdout's unicode
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 5 Nov 2011 23:38:45 +0000 (00:38 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 5 Nov 2011 23:38:45 +0000 (00:38 +0100)
error handler in interactive mode (when calling into PyOS_Readline()).

1  2 
Lib/test/test_builtin.py
Misc/NEWS
Python/bltinmodule.c

index 587c1c04e92ed98d88512e6f9b5e75cf8abedd00,40c1ab4fd050d2d30369c1938c2e00279563e5c2..d4e293cee2a88fd4f374860d8f5ecbac6c0c15d2
@@@ -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 Misc/NEWS
Simple merge
index 0c14d7e3261656aaa43897fa73d227a7f59d1e23,9e37d21b5df5729f74fb17be372e984268d1e6a5..4d960b8d1c5b8847f3e6b32816bbbc6732be254a
@@@ -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;