Skip to content

Commit c0c6514

Browse files
authored
gh-140482: Avoid changing terminal settings in test_pty (gh-142202)
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
1 parent 62423c9 commit c0c6514

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

Lib/test/test_pty.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
is_android, is_apple_mobile, is_wasm32, reap_children, verbose, warnings_helper
44
)
55
from test.support.import_helper import import_module
6-
from test.support.os_helper import TESTFN, unlink
76

87
# Skip these tests if termios is not available
98
import_module('termios')
@@ -299,26 +298,27 @@ def test_master_read(self):
299298

300299
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
301300
def test_spawn_doesnt_hang(self):
302-
self.addCleanup(unlink, TESTFN)
303-
with open(TESTFN, 'wb') as f:
304-
STDOUT_FILENO = 1
305-
dup_stdout = os.dup(STDOUT_FILENO)
306-
os.dup2(f.fileno(), STDOUT_FILENO)
307-
buf = b''
308-
def master_read(fd):
309-
nonlocal buf
310-
data = os.read(fd, 1024)
311-
buf += data
312-
return data
301+
# gh-140482: Do the test in a pty.fork() child to avoid messing
302+
# with the interactive test runner's terminal settings.
303+
pid, fd = pty.fork()
304+
if pid == pty.CHILD:
305+
pty.spawn([sys.executable, '-c', 'print("hi there")'])
306+
os._exit(0)
307+
308+
try:
309+
buf = bytearray()
313310
try:
314-
pty.spawn([sys.executable, '-c', 'print("hi there")'],
315-
master_read)
316-
finally:
317-
os.dup2(dup_stdout, STDOUT_FILENO)
318-
os.close(dup_stdout)
319-
self.assertEqual(buf, b'hi there\r\n')
320-
with open(TESTFN, 'rb') as f:
321-
self.assertEqual(f.read(), b'hi there\r\n')
311+
while (data := os.read(fd, 1024)) != b'':
312+
buf.extend(data)
313+
except OSError as e:
314+
if e.errno != errno.EIO:
315+
raise
316+
317+
(pid, status) = os.waitpid(pid, 0)
318+
self.assertEqual(status, 0)
319+
self.assertEqual(buf.take_bytes(), b"hi there\r\n")
320+
finally:
321+
os.close(fd)
322322

323323
class SmallPtyTests(unittest.TestCase):
324324
"""These tests don't spawn children or hang."""

0 commit comments

Comments
 (0)