From fca5112f17f1fda9206e0d3b313c6f8b5a23ee9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=87=E5=BD=AC=E5=AE=87?= <3431359639@qq.com> Date: Mon, 24 Aug 2026 12:38:11 +0800 Subject: [PATCH] gh-126253: Ignore unknown Windows file attribute bits in scandir test --- Lib/test/test_os/test_os.py | 43 +++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 81b3043eb7e75b..36e476e3fc589c 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -84,6 +84,17 @@ HAVE_WHEEL_GROUP = sys.platform.startswith('freebsd') and os.getgid() == 0 +def _get_file_attribute_mask(): + mask = 0 + for name in dir(stat): + if name.startswith("FILE_ATTRIBUTE_"): + mask |= getattr(stat, name) + return mask + + +_FILE_ATTRIBUTE_MASK = _get_file_attribute_mask() + + def requires_os_func(name): return unittest.skipUnless(hasattr(os, name), 'requires os.%s' % name) @@ -5004,8 +5015,15 @@ def assert_stat_equal(self, stat1, stat2, skip_fields): if attr in ("st_dev", "st_ino", "st_nlink", "st_ctime", "st_ctime_ns"): continue - self.assertEqual(getattr(stat1, attr), - getattr(stat2, attr), + value1 = getattr(stat1, attr) + value2 = getattr(stat2, attr) + if attr == "st_file_attributes": + # Filesystems may report attribute bits that aren't + # exposed by the stat module. + value1 &= _FILE_ATTRIBUTE_MASK + value2 &= _FILE_ATTRIBUTE_MASK + self.assertEqual(value1, + value2, (stat1, stat2, attr)) else: self.assertEqual(stat1, stat2) @@ -5093,6 +5111,27 @@ def test_attributes(self): entry = entries['symlink_file.txt'] self.check_entry(entry, 'symlink_file.txt', False, True, True) + @unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') + def test_attributes_unknown_bits(self): + base = os.stat(self.path) + file_attributes = base.st_file_attributes + unknown_attribute = 0x10000000 + self.assertFalse(unknown_attribute & _FILE_ATTRIBUTE_MASK) + + stat1 = os.stat_result( + tuple(base), {"st_file_attributes": file_attributes}) + stat2 = os.stat_result( + tuple(base), + {"st_file_attributes": file_attributes | unknown_attribute}) + self.assert_stat_equal(stat1, stat2, True) + + stat3 = os.stat_result( + tuple(base), + {"st_file_attributes": + file_attributes ^ stat.FILE_ATTRIBUTE_READONLY}) + with self.assertRaises(AssertionError): + self.assert_stat_equal(stat1, stat3, True) + @unittest.skipIf(sys.platform != 'win32', "Can only test junctions with creation on win32.") def test_attributes_junctions(self): dirname = os.path.join(self.path, "tgtdir")