From b44cd567fc409f542f81161bd4e0281e27db818b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 5 Dec 2025 21:20:42 +0100 Subject: [PATCH] [3.13] gh-140482: Avoid changing terminal settings in test_pty (gh-142202) (gh-142238) The previous test_spawn_doesnt_hang test had a few problems: * It would cause ENV CHANGED failures if other tests were running concurrently due to stty changes * Typing while the test was running could cause it to fail (cherry picked from commit c0c65141b37029bfb364094a6dfb4c75ebf8359e) Co-authored-by: Sam Gross --- Lib/test/test_pty.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index c1728f5019d0..fad34d5cb1c1 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -3,7 +3,6 @@ from test.support import ( is_android, is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose ) from test.support.import_helper import import_module -from test.support.os_helper import TESTFN, unlink # Skip these tests if termios is not available import_module('termios') @@ -297,26 +296,27 @@ class PtyTest(unittest.TestCase): self.assertEqual(data, b"") def test_spawn_doesnt_hang(self): - self.addCleanup(unlink, TESTFN) - with open(TESTFN, 'wb') as f: - STDOUT_FILENO = 1 - dup_stdout = os.dup(STDOUT_FILENO) - os.dup2(f.fileno(), STDOUT_FILENO) - buf = b'' - def master_read(fd): - nonlocal buf - data = os.read(fd, 1024) - buf += data - return data + # gh-140482: Do the test in a pty.fork() child to avoid messing + # with the interactive test runner's terminal settings. + pid, fd = pty.fork() + if pid == pty.CHILD: + pty.spawn([sys.executable, '-c', 'print("hi there")']) + os._exit(0) + + try: + buf = bytearray() try: - pty.spawn([sys.executable, '-c', 'print("hi there")'], - master_read) - finally: - os.dup2(dup_stdout, STDOUT_FILENO) - os.close(dup_stdout) - self.assertEqual(buf, b'hi there\r\n') - with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'hi there\r\n') + while (data := os.read(fd, 1024)) != b'': + buf.extend(data) + except OSError as e: + if e.errno != errno.EIO: + raise + + (pid, status) = os.waitpid(pid, 0) + self.assertEqual(status, 0) + self.assertEqual(bytes(buf), b"hi there\r\n") + finally: + os.close(fd) class SmallPtyTests(unittest.TestCase): """These tests don't spawn children or hang.""" -- 2.47.3