https://github.com/python/cpython/commit/9743d88334addede9763c73817bda6b1ad0562c7
commit: 9743d88334addede9763c73817bda6b1ad0562c7
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: colesbury <[email protected]>
date: 2026-03-16T11:42:47-04:00
summary:

[3.14] gh-135329: Remove flaky test_repl_eio test (gh-145932) (#146028)

The test doesn't actually test any pyrepl code (it runs Python with -S)
and has a race condition that causes intermittent timeouts on CI.
(cherry picked from commit e18abc6a1f1b60434b529d4c1ff4855acde0fd13)

Co-authored-by: Sam Gross <[email protected]>

files:
D Lib/test/test_pyrepl/eio_test_script.py
M Lib/test/test_pyrepl/test_unix_console.py

diff --git a/Lib/test/test_pyrepl/eio_test_script.py 
b/Lib/test/test_pyrepl/eio_test_script.py
deleted file mode 100644
index e3ea6caef58e80..00000000000000
--- a/Lib/test/test_pyrepl/eio_test_script.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import errno
-import fcntl
-import os
-import pty
-import signal
-import sys
-import termios
-
-
-def handler(sig, f):
-    pass
-
-
-def create_eio_condition():
-    # SIGINT handler used to produce an EIO.
-    # See https://github.com/python/cpython/issues/135329.
-    try:
-        master_fd, slave_fd = pty.openpty()
-        child_pid = os.fork()
-        if child_pid == 0:
-            try:
-                os.setsid()
-                fcntl.ioctl(slave_fd, termios.TIOCSCTTY, 0)
-                child_process_group_id = os.getpgrp()
-                grandchild_pid = os.fork()
-                if grandchild_pid == 0:
-                    os.setpgid(0, 0)      # set process group for grandchild
-                    os.dup2(slave_fd, 0)  # redirect stdin
-                    if slave_fd > 2:
-                        os.close(slave_fd)
-                    # Fork grandchild for terminal control manipulation
-                    if os.fork() == 0:
-                        sys.exit(0)  # exit the child process that was just 
obtained
-                    else:
-                        try:
-                            os.tcsetpgrp(0, child_process_group_id)
-                        except OSError:
-                            pass
-                        sys.exit(0)
-                else:
-                    # Back to child
-                    try:
-                        os.setpgid(grandchild_pid, grandchild_pid)
-                    except ProcessLookupError:
-                        pass
-                    os.tcsetpgrp(slave_fd, grandchild_pid)
-                    if slave_fd > 2:
-                        os.close(slave_fd)
-                    os.waitpid(grandchild_pid, 0)
-                    # Manipulate terminal control to create EIO condition
-                    os.tcsetpgrp(master_fd, child_process_group_id)
-                    # Now try to read from master - this might cause EIO
-                    try:
-                        os.read(master_fd, 1)
-                    except OSError as e:
-                        if e.errno == errno.EIO:
-                            print(f"Setup created EIO condition: {e}", 
file=sys.stderr)
-                    sys.exit(0)
-            except Exception as setup_e:
-                print(f"Setup error: {setup_e}", file=sys.stderr)
-                sys.exit(1)
-        else:
-            # Parent process
-            os.close(slave_fd)
-            os.waitpid(child_pid, 0)
-            # Now replace stdin with master_fd and try to read
-            os.dup2(master_fd, 0)
-            os.close(master_fd)
-            # This should now trigger EIO
-            print(f"Unexpectedly got input: {input()!r}", file=sys.stderr)
-            sys.exit(0)
-    except OSError as e:
-        if e.errno == errno.EIO:
-            print(f"Got EIO: {e}", file=sys.stderr)
-            sys.exit(1)
-        elif e.errno == errno.ENXIO:
-            print(f"Got ENXIO (no such device): {e}", file=sys.stderr)
-            sys.exit(1)  # Treat ENXIO as success too
-        else:
-            print(f"Got other OSError: errno={e.errno} {e}", file=sys.stderr)
-            sys.exit(2)
-    except EOFError as e:
-        print(f"Got EOFError: {e}", file=sys.stderr)
-        sys.exit(3)
-    except Exception as e:
-        print(f"Got unexpected error: {type(e).__name__}: {e}", 
file=sys.stderr)
-        sys.exit(4)
-
-
-if __name__ == "__main__":
-    # Set up signal handler for coordination
-    signal.signal(signal.SIGUSR1, lambda *a: create_eio_condition())
-    print("READY", flush=True)
-    signal.pause()
diff --git a/Lib/test/test_pyrepl/test_unix_console.py 
b/Lib/test/test_pyrepl/test_unix_console.py
index 680adbc2d968f0..a1ee6d4878fe93 100644
--- a/Lib/test/test_pyrepl/test_unix_console.py
+++ b/Lib/test/test_pyrepl/test_unix_console.py
@@ -2,14 +2,12 @@
 import itertools
 import os
 import signal
-import subprocess
 import sys
 import threading
 import unittest
 from functools import partial
-from test import support
 from test.support import os_helper, force_not_colorized_test_class
-from test.support import script_helper, threading_helper
+from test.support import threading_helper
 
 from unittest import TestCase
 from unittest.mock import MagicMock, call, patch, ANY, Mock
@@ -369,34 +367,3 @@ def test_eio_error_handling_in_restore(self, 
mock_tcgetattr, mock_tcsetattr):
 
         # EIO error should be handled gracefully in restore()
         console.restore()
-
-    @unittest.skipUnless(sys.platform == "linux", "Only valid on Linux")
-    def test_repl_eio(self):
-        # Use the pty-based approach to simulate EIO error
-        script_path = os.path.join(os.path.dirname(__file__), 
"eio_test_script.py")
-
-        proc = script_helper.spawn_python(
-            "-S", script_path,
-            stderr=subprocess.PIPE,
-            text=True
-        )
-
-        ready_line = proc.stdout.readline().strip()
-        if ready_line != "READY" or proc.poll() is not None:
-            self.fail("Child process failed to start properly")
-
-        os.kill(proc.pid, signal.SIGUSR1)
-        # sleep for pty to settle
-        _, err = proc.communicate(timeout=support.LONG_TIMEOUT)
-        self.assertEqual(
-            proc.returncode,
-            1,
-            f"Expected EIO/ENXIO error, got return code {proc.returncode}",
-        )
-        self.assertTrue(
-            (
-                "Got EIO:" in err
-                or "Got ENXIO:" in err
-            ),
-            f"Expected EIO/ENXIO error message in stderr: {err}",
-        )

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to