https://github.com/python/cpython/commit/f8d4ca42ae2b0da9e3df65884b6e55f2e4035070
commit: f8d4ca42ae2b0da9e3df65884b6e55f2e4035070
branch: 3.13
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2025-04-23T19:17:51Z
summary:

[3.13] gh-83994, gh-132843: Fix and improve test_ioctl (GH-132848) (GH-132850)

* Skip test_ioctl_tcflush if termios.TCFLSH is not available.
* Do not skip ALL ioctl() tests when /dev/tty is not available.
(cherry picked from commit 4b4b9fbb06198f65424ed5be06c59f8b2801b99b)

files:
M Lib/test/test_ioctl.py

diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py
index c1aac8eec58330..cc625812dc3d03 100644
--- a/Lib/test/test_ioctl.py
+++ b/Lib/test/test_ioctl.py
@@ -1,32 +1,35 @@
 import array
+import os
+import struct
+import threading
 import unittest
 from test.support import get_attribute
+from test.support import threading_helper
 from test.support.import_helper import import_module
-import os, struct
 fcntl = import_module('fcntl')
 termios = import_module('termios')
-get_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature
-
-try:
-    tty = open("/dev/tty", "rb")
-except OSError:
-    raise unittest.SkipTest("Unable to open /dev/tty")
-else:
-    with tty:
-        # Skip if another process is in foreground
-        r = fcntl.ioctl(tty, termios.TIOCGPGRP, struct.pack("i", 0))
-    rpgrp = struct.unpack("i", r)[0]
-    if rpgrp not in (os.getpgrp(), os.getsid(0)):
-        raise unittest.SkipTest("Neither the process group nor the session "
-                                "are attached to /dev/tty")
-    del tty, r, rpgrp
 
 try:
     import pty
 except ImportError:
     pty = None
 
-class IoctlTests(unittest.TestCase):
+class IoctlTestsTty(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        TIOCGPGRP = get_attribute(termios, 'TIOCGPGRP')
+        try:
+            tty = open("/dev/tty", "rb")
+        except OSError:
+            raise unittest.SkipTest("Unable to open /dev/tty")
+        with tty:
+            # Skip if another process is in foreground
+            r = fcntl.ioctl(tty, TIOCGPGRP, struct.pack("i", 0))
+        rpgrp = struct.unpack("i", r)[0]
+        if rpgrp not in (os.getpgrp(), os.getsid(0)):
+            raise unittest.SkipTest("Neither the process group nor the session 
"
+                                    "are attached to /dev/tty")
+
     def test_ioctl_immutable_buf(self):
         # If this process has been put into the background, TIOCGPGRP returns
         # the session ID instead of the process group id.
@@ -132,31 +135,34 @@ def test_ioctl_mutate_2048(self):
         self._check_ioctl_mutate_len(2048)
         self.assertRaises(ValueError, self._check_ioctl_not_mutate_len, 2048)
 
+
+@unittest.skipIf(pty is None, 'pty module required')
+class IoctlTestsPty(unittest.TestCase):
+    def setUp(self):
+        self.master_fd, self.slave_fd = pty.openpty()
+        self.addCleanup(os.close, self.slave_fd)
+        self.addCleanup(os.close, self.master_fd)
+
+    @unittest.skipUnless(hasattr(termios, 'TCFLSH'), 'requires termios.TCFLSH')
     def test_ioctl_tcflush(self):
-        with open("/dev/tty", "rb") as tty:
-            r = fcntl.ioctl(tty, termios.TCFLSH, termios.TCIFLUSH)
-            self.assertEqual(r, 0)
+        r = fcntl.ioctl(self.slave_fd, termios.TCFLSH, termios.TCIFLUSH)
+        self.assertEqual(r, 0)
+        r = fcntl.ioctl(self.slave_fd, termios.TCFLSH, termios.TCOFLUSH)
+        self.assertEqual(r, 0)
 
     def test_ioctl_signed_unsigned_code_param(self):
-        if not pty:
-            raise unittest.SkipTest('pty module required')
-        mfd, sfd = pty.openpty()
-        try:
-            if termios.TIOCSWINSZ < 0:
-                set_winsz_opcode_maybe_neg = termios.TIOCSWINSZ
-                set_winsz_opcode_pos = termios.TIOCSWINSZ & 0xffffffff
-            else:
-                set_winsz_opcode_pos = termios.TIOCSWINSZ
-                set_winsz_opcode_maybe_neg, = struct.unpack("i",
-                        struct.pack("I", termios.TIOCSWINSZ))
-
-            our_winsz = struct.pack("HHHH",80,25,0,0)
-            # test both with a positive and potentially negative ioctl code
-            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_pos, our_winsz)
-            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_maybe_neg, our_winsz)
-        finally:
-            os.close(mfd)
-            os.close(sfd)
+        if termios.TIOCSWINSZ < 0:
+            set_winsz_opcode_maybe_neg = termios.TIOCSWINSZ
+            set_winsz_opcode_pos = termios.TIOCSWINSZ & 0xffffffff
+        else:
+            set_winsz_opcode_pos = termios.TIOCSWINSZ
+            set_winsz_opcode_maybe_neg, = struct.unpack("i",
+                    struct.pack("I", termios.TIOCSWINSZ))
+
+        our_winsz = struct.pack("HHHH",80,25,0,0)
+        # test both with a positive and potentially negative ioctl code
+        new_winsz = fcntl.ioctl(self.master_fd, set_winsz_opcode_pos, 
our_winsz)
+        new_winsz = fcntl.ioctl(self.master_fd, set_winsz_opcode_maybe_neg, 
our_winsz)
 
 
 if __name__ == "__main__":

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to