diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py index db911b3e1f0b91..5e45df55b83700 100644 --- a/Lib/_pyrepl/console.py +++ b/Lib/_pyrepl/console.py @@ -24,6 +24,7 @@ from abc import ABC, abstractmethod import ast import code +import io from dataclasses import dataclass, field import os.path import sys @@ -177,7 +178,19 @@ def _excepthook(self, typ, value, tb): def runcode(self, code): try: + temp_output = io.StringIO() + old_stdout = sys.stdout + sys.stdout = temp_output exec(code, self.locals) + output = "" + if hasattr(sys.stdout, "getvalue"): + output = sys.stdout.getvalue() + # Avoid restoring old stdout if it has been changed during exec + if sys.stdout is temp_output: + sys.stdout = old_stdout + if not output.endswith("\n"): + output += "\n" + print(output, end="") except SystemExit: raise except BaseException: diff --git a/Lib/test/test_pyrepl/test_pyrepl.py b/Lib/test/test_pyrepl/test_pyrepl.py index 3540d2a5a41662..73a04025023321 100644 --- a/Lib/test/test_pyrepl/test_pyrepl.py +++ b/Lib/test/test_pyrepl/test_pyrepl.py @@ -1344,6 +1344,16 @@ def test_keyboard_interrupt_after_isearch(self): output, exit_code = self.run_repl(["\x12", "\x03", "exit"]) self.assertEqual(exit_code, 0) + def test_newline_after_print_ending_in_space(self): + commands = ("print('abcdefg' * 250 + 'Z', end=' ')\n" + "exit()\n") + output, exit_code = self.run_repl(commands) + self.assertEqual(exit_code, 0) + print(output) + self.assertIn("Z \r\n", output) + expected = "abcdefg" * 200 + "Z " + "\r\n" + self.assertIn(expected, output) + def test_prompt_after_help(self): output, exit_code = self.run_repl(["help", "q", "exit"])