Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2813,7 +2813,8 @@ def _run_child(self, child, terminal_input):
def check_input_tty(self, prompt, terminal_input, stdio_encoding=None, *,
expected=None,
stdin_errors='surrogateescape',
stdout_errors='replace'):
stdout_errors='replace',
terminal_input_end=b'\r\n'):
if not sys.stdin.isatty() or not sys.stdout.isatty():
self.skipTest("stdin and stdout must be ttys")
def child(wpipe):
Expand All @@ -2831,7 +2832,7 @@ def child(wpipe):
except BaseException as e:
print(ascii(f'{e.__class__.__name__}: {e!s}'), file=wpipe)
with self.detach_readline():
lines = self.run_child(child, terminal_input + b"\r\n")
lines = self.run_child(child, terminal_input + terminal_input_end)
# Check we did exercise the GNU readline path
self.assertIn(lines[0], {'tty = True', 'tty = False'})
if lines[0] != 'tty = True':
Expand Down Expand Up @@ -2869,6 +2870,9 @@ def test_input_tty(self):
# Test input() functionality when wired to a tty
self.check_input_tty("prompt", b"quux")

def test_input_tty_eof_without_newline(self):
self.check_input_tty("prompt", b"quux", terminal_input_end=b"\x04")

def test_input_tty_non_ascii(self):
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
self.check_input_tty("prompté", b"quux\xc3\xa9", "utf-8")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix :func:`input` assuming the last character being a ``'\n'`` and removing it.
11 changes: 8 additions & 3 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2586,9 +2586,14 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
result = NULL;
}
else {
len--; /* strip trailing '\n' */
if (len != 0 && s[len-1] == '\r')
len--; /* strip trailing '\r' */
/* strip trailing '\n' */
if (s[len-1] == '\n') {
len--;
}
/* strip trailing '\r' */
if (len != 0 && s[len-1] == '\r') {
len--;
}
result = PyUnicode_Decode(s, len, stdin_encoding_str,
stdin_errors_str);
}
Expand Down
Loading