Skip to content

Commit 02bfdb3

Browse files
author
Victor Stinner
committed
Merged revisions 88530 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88530 | victor.stinner | 2011-02-23 13:07:37 +0100 (mer., 23 févr. 2011) | 4 lines 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'). ........
1 parent 9f6cbe0 commit 02bfdb3

File tree

4 files changed

+49
-6
lines changed

4 files changed

+49
-6
lines changed

Lib/test/test_cmd_line.py

+26
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import sys
88
import subprocess
9+
import tempfile
910
from test.script_helper import spawn_python, kill_python, assert_python_ok, assert_python_failure
1011

1112

@@ -239,6 +240,31 @@ def test_displayhook_unencodable(self):
239240
escaped = repr(text).encode(encoding, 'backslashreplace')
240241
self.assertIn(escaped, data)
241242

243+
def check_input(self, code, expected):
244+
with tempfile.NamedTemporaryFile("wb+") as stdin:
245+
sep = os.linesep.encode('ASCII')
246+
stdin.write(sep.join((b'abc', b'def')))
247+
stdin.flush()
248+
stdin.seek(0)
249+
with subprocess.Popen(
250+
(sys.executable, "-c", code),
251+
stdin=stdin, stdout=subprocess.PIPE) as proc:
252+
stdout, stderr = proc.communicate()
253+
self.assertEqual(stdout.rstrip(), expected)
254+
255+
def test_stdin_readline(self):
256+
# Issue #11272: check that sys.stdin.readline() replaces '\r\n' by '\n'
257+
# on Windows (sys.stdin is opened in binary mode)
258+
self.check_input(
259+
"import sys; print(repr(sys.stdin.readline()))",
260+
b"'abc\\n'")
261+
262+
def test_builtin_input(self):
263+
# Issue #11272: check that input() strips newlines ('\n' or '\r\n')
264+
self.check_input(
265+
"print(repr(input()))",
266+
b"'abc'")
267+
242268

243269
def test_main():
244270
test.support.run_unittest(CmdLineTest)

Misc/NEWS

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.2.1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #11272: On Windows, input() strips '\r' (and not only '\n'), and
14+
sys.stdin uses universal newline (replace '\r\n' by '\n').
15+
1316
- Check for NULL result in PyType_FromSpec.
1417

1518
Library
@@ -26,7 +29,7 @@ Library
2629
32-bit Windows.
2730

2831
- Issue #11089: Fix performance issue limiting the use of ConfigParser()
29-
with large config files.
32+
with large config files.
3033

3134
- Issue #10276: Fix the results of zlib.crc32() and zlib.adler32() on buffers
3235
larger than 4GB. Patch by Nadeem Vawda.

Python/bltinmodule.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,7 @@ builtin_input(PyObject *self, PyObject *args)
16211621
PyObject *stdin_encoding;
16221622
char *stdin_encoding_str;
16231623
PyObject *result;
1624+
size_t len;
16241625

16251626
stdin_encoding = PyObject_GetAttrString(fin, "encoding");
16261627
if (!stdin_encoding)
@@ -1685,19 +1686,23 @@ builtin_input(PyObject *self, PyObject *args)
16851686
Py_DECREF(stdin_encoding);
16861687
return NULL;
16871688
}
1688-
if (*s == '\0') {
1689+
1690+
len = strlen(s);
1691+
if (len == 0) {
16891692
PyErr_SetNone(PyExc_EOFError);
16901693
result = NULL;
16911694
}
1692-
else { /* strip trailing '\n' */
1693-
size_t len = strlen(s);
1695+
else {
16941696
if (len > PY_SSIZE_T_MAX) {
16951697
PyErr_SetString(PyExc_OverflowError,
16961698
"input: input too long");
16971699
result = NULL;
16981700
}
16991701
else {
1700-
result = PyUnicode_Decode(s, len-1, stdin_encoding_str, NULL);
1702+
len--; /* strip trailing '\n' */
1703+
if (len != 0 && s[len-1] == '\r')
1704+
len--; /* strip trailing '\r' */
1705+
result = PyUnicode_Decode(s, len, stdin_encoding_str, NULL);
17011706
}
17021707
}
17031708
Py_DECREF(stdin_encoding);

Python/pythonrun.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ create_stdio(PyObject* io,
778778
{
779779
PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
780780
const char* mode;
781+
const char* newline;
781782
PyObject *line_buffering;
782783
int buffering, isatty;
783784

@@ -828,9 +829,17 @@ create_stdio(PyObject* io,
828829
Py_CLEAR(raw);
829830
Py_CLEAR(text);
830831

832+
newline = "\n";
833+
#ifdef MS_WINDOWS
834+
if (!write_mode) {
835+
/* translate \r\n to \n for sys.stdin on Windows */
836+
newline = NULL;
837+
}
838+
#endif
839+
831840
stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO",
832841
buf, encoding, errors,
833-
"\n", line_buffering);
842+
newline, line_buffering);
834843
Py_CLEAR(buf);
835844
if (stream == NULL)
836845
goto error;

0 commit comments

Comments
 (0)