Skip to content

Commit b44cd56

Browse files
[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 c0c6514) Co-authored-by: Sam Gross <colesbury@gmail.com>
1 parent 10d1e93 commit b44cd56

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_emscripten, is_wasi, reap_children, verbose
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')
@@ -297,26 +296,27 @@ def test_master_read(self):
297296
self.assertEqual(data, b"")
298297

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

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

0 commit comments

Comments
 (0)