From: Victor Stinner Date: Sat, 16 May 2026 08:50:55 +0000 (+0200) Subject: gh-149879: Fix test_os on Cygwin (#149910) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=436a6f289402553ca2bf1308881d85861e5d8a22;p=thirdparty%2FPython%2Fcpython.git gh-149879: Fix test_os on Cygwin (#149910) --- diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 7e670e5a139d..e71c28424e09 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -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) diff --git a/Lib/test/test_os/test_posix.py b/Lib/test/test_os/test_posix.py index 0e8495a4eff2..d0a662a09182 100644 --- a/Lib/test/test_os/test_posix.py +++ b/Lib/test/test_os/test_posix.py @@ -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)