]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149879: Fix test_os on Cygwin (#149910)
authorVictor Stinner <vstinner@python.org>
Sat, 16 May 2026 08:50:55 +0000 (10:50 +0200)
committerGitHub <noreply@github.com>
Sat, 16 May 2026 08:50:55 +0000 (10:50 +0200)
Lib/test/test_os/test_os.py
Lib/test/test_os/test_posix.py

index 7e670e5a139d99976457b9c46b0c42cb8345222b..e71c28424e095f2596a3e43aba41d88d88d907b7 100644 (file)
@@ -1867,7 +1867,9 @@ class WalkTests(unittest.TestCase):
 
         walk_it = self.walk(self.tmp1_path, follow_symlinks=True)
         if self.is_fwalk:
-            self.assertRaises(NotADirectoryError, next, walk_it)
+            with self.assertRaises(OSError) as cm:
+                next(walk_it)
+            self.assertIn(cm.exception.errno, (errno.ENOTDIR, errno.EINVAL))
         self.assertRaises(StopIteration, next, walk_it)
 
     @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
@@ -2269,6 +2271,8 @@ class ChownFileTests(unittest.TestCase):
 
     @requires_non_root_user
     @unittest.skipUnless(len(all_users) > 1, "test needs and more than one user")
+    @unittest.skipIf(sys.platform == 'cygwin',
+                         'chown() can set any uid on Cygwin')
     def test_chown_without_permission(self):
         uid_1, uid_2 = all_users[:2]
         gid = os.stat(os_helper.TESTFN).st_gid
@@ -4051,10 +4055,11 @@ class TimerfdTests(unittest.TestCase):
         initial_expiration = 0.1
         os.timerfd_settime(fd, initial=initial_expiration, interval=0)
 
-        # read() raises OSError with errno is EAGAIN for non-blocking timer.
-        with self.assertRaises(OSError) as ctx:
-            self.read_count_signaled(fd)
-        self.assertEqual(ctx.exception.errno, errno.EAGAIN)
+        if sys.platform != 'cygwin':
+            # read() raises OSError with errno is EAGAIN for non-blocking timer.
+            with self.assertRaises(OSError) as ctx:
+                self.read_count_signaled(fd)
+            self.assertEqual(ctx.exception.errno, errno.EAGAIN)
 
         # Wait more than 0.1 seconds
         time.sleep(initial_expiration + 0.1)
@@ -4235,12 +4240,19 @@ class TimerfdTests(unittest.TestCase):
 
         # 2nd call
         next_expiration_ns, interval_ns2 = os.timerfd_settime_ns(fd, initial=initial_expiration_ns, interval=interval_ns)
-        self.assertEqual(interval_ns2, interval_ns)
+        CYGWIN = (sys.platform == 'cygwin')
+        if not CYGWIN:
+            self.assertEqual(interval_ns2, interval_ns)
+        else:
+            self.assertEqual(interval_ns2, 0)
         self.assertEqual(next_expiration_ns, initial_expiration_ns)
 
         # timerfd_gettime
         next_expiration_ns, interval_ns2 = os.timerfd_gettime_ns(fd)
-        self.assertEqual(interval_ns2, interval_ns)
+        if not CYGWIN:
+            self.assertEqual(interval_ns2, interval_ns)
+        else:
+            self.assertEqual(interval_ns2, 0)
         self.assertLessEqual(next_expiration_ns, initial_expiration_ns)
 
         self.assertAlmostEqual(next_expiration_ns, initial_expiration_ns, delta=limit_error)
index 0e8495a4eff2ed4004b97681091898e809ad77cc..d0a662a091829e884daf11ce10dfb94e0525cd14 100644 (file)
@@ -142,8 +142,8 @@ class PosixTester(unittest.TestCase):
         self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
 
         # If a non-privileged user invokes it, it should fail with OSError
-        # EPERM.
-        if os.getuid() != 0:
+        # EPERM. On Cygwin, initgroups(name, 13) does not fail.
+        if os.getuid() != 0 and sys.platform != 'cygwin':
             try:
                 name = pwd.getpwuid(posix.getuid()).pw_name
             except KeyError:
@@ -597,7 +597,9 @@ class PosixTester(unittest.TestCase):
             posix.sysconf(1.23)
 
         arg_max = posix.sysconf("SC_ARG_MAX")
-        self.assertGreater(arg_max, 0)
+        # SC_ARG_MAX is -1 on Cygwin
+        if sys.platform != 'cygwin':
+            self.assertGreater(arg_max, 0)
         self.assertEqual(
             posix.sysconf(posix.sysconf_names["SC_ARG_MAX"]), arg_max)
 
@@ -1943,6 +1945,14 @@ class _PosixSpawnMixin:
         # directories in the $PATH that are not accessible.
         except (FileNotFoundError, PermissionError) as exc:
             self.assertEqual(exc.filename, no_such_executable)
+
+            # On Cygwin, os.posix_spawn() creates a child process even if the
+            # executable doesn't exist. We have to reap this process.
+            if sys.platform == 'cygwin':
+                for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
+                    pid, status = os.waitpid(-1, os.WNOHANG)
+                    if pid != 0:
+                        break
         else:
             pid2, status = os.waitpid(pid, 0)
             self.assertEqual(pid2, pid)