[Python-checkins] r88530 - in python/branches/py3k: Lib/test/test_cmd_line.py Misc/NEWS Python/bltinmodule.c Python/pythonrun.c

victor.stinner python-checkins at python.org
Wed Feb 23 13:07:38 CET 2011


Author: victor.stinner
Date: Wed Feb 23 13:07:37 2011
New Revision: 88530

Log:
Issue #11272: Fix input() and sys.stdin for Windows newline

On Windows, input() strips '\r' (and not only '\n'), and sys.stdin uses
universal newline (replace '\r\n' by '\n').

Modified:
   python/branches/py3k/Lib/test/test_cmd_line.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/bltinmodule.c
   python/branches/py3k/Python/pythonrun.c

Modified: python/branches/py3k/Lib/test/test_cmd_line.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cmd_line.py	(original)
+++ python/branches/py3k/Lib/test/test_cmd_line.py	Wed Feb 23 13:07:37 2011
@@ -6,6 +6,7 @@
 import os
 import sys
 import subprocess
+import tempfile
 from test.script_helper import spawn_python, kill_python, assert_python_ok, assert_python_failure
 
 
@@ -239,6 +240,31 @@
             escaped = repr(text).encode(encoding, 'backslashreplace')
             self.assertIn(escaped, data)
 
+    def check_input(self, code, expected):
+        with tempfile.NamedTemporaryFile("wb+") as stdin:
+            sep = os.linesep.encode('ASCII')
+            stdin.write(sep.join((b'abc', b'def')))
+            stdin.flush()
+            stdin.seek(0)
+            with subprocess.Popen(
+                (sys.executable, "-c", code),
+                stdin=stdin, stdout=subprocess.PIPE) as proc:
+                stdout, stderr = proc.communicate()
+        self.assertEqual(stdout.rstrip(), expected)
+
+    def test_stdin_readline(self):
+        # Issue #11272: check that sys.stdin.readline() replaces '\r\n' by '\n'
+        # on Windows (sys.stdin is opened in binary mode)
+        self.check_input(
+            "import sys; print(repr(sys.stdin.readline()))",
+            b"'abc\\n'")
+
+    def test_builtin_input(self):
+        # Issue #11272: check that input() strips newlines ('\n' or '\r\n')
+        self.check_input(
+            "print(repr(input()))",
+            b"'abc'")
+
 
 def test_main():
     test.support.run_unittest(CmdLineTest)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Feb 23 13:07:37 2011
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #11272: On Windows, input() strips '\r' (and not only '\n'), and
+  sys.stdin uses universal newline (replace '\r\n' by '\n').
+
 - Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
   narrow build.
 

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Wed Feb 23 13:07:37 2011
@@ -1618,6 +1618,7 @@
         PyObject *stdin_encoding;
         char *stdin_encoding_str;
         PyObject *result;
+        size_t len;
 
         stdin_encoding = PyObject_GetAttrString(fin, "encoding");
         if (!stdin_encoding)
@@ -1682,19 +1683,23 @@
             Py_DECREF(stdin_encoding);
             return NULL;
         }
-        if (*s == '\0') {
+
+        len = strlen(s);
+        if (len == 0) {
             PyErr_SetNone(PyExc_EOFError);
             result = NULL;
         }
-        else { /* strip trailing '\n' */
-            size_t len = strlen(s);
+        else {
             if (len > PY_SSIZE_T_MAX) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "input: input too long");
                 result = NULL;
             }
             else {
-                result = PyUnicode_Decode(s, len-1, stdin_encoding_str, NULL);
+                len--;   /* strip trailing '\n' */
+                if (len != 0 && s[len-1] == '\r')
+                    len--;   /* strip trailing '\r' */
+                result = PyUnicode_Decode(s, len, stdin_encoding_str, NULL);
             }
         }
         Py_DECREF(stdin_encoding);

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Wed Feb 23 13:07:37 2011
@@ -778,6 +778,7 @@
 {
     PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
     const char* mode;
+    const char* newline;
     PyObject *line_buffering;
     int buffering, isatty;
 
@@ -828,9 +829,17 @@
     Py_CLEAR(raw);
     Py_CLEAR(text);
 
+    newline = "\n";
+#ifdef MS_WINDOWS
+    if (!write_mode) {
+        /* translate \r\n to \n for sys.stdin on Windows */
+        newline = NULL;
+    }
+#endif
+
     stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO",
                                  buf, encoding, errors,
-                                 "\n", line_buffering);
+                                 newline, line_buffering);
     Py_CLEAR(buf);
     if (stream == NULL)
         goto error;


More information about the Python-checkins mailing list