gh-83714: Fix os.statx() tests on tmpfs: st_birthtime can be None (#140407)

This commit is contained in:
Victor Stinner 2025-10-21 12:24:49 +02:00 committed by GitHub
parent 5c41666ec4
commit fe4b60208e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -648,9 +648,10 @@ def check_timestamp_agreement(self, result, names):
# Make sure that the st_?time and st_?time_ns fields roughly agree # Make sure that the st_?time and st_?time_ns fields roughly agree
# (they should always agree up to around tens-of-microseconds) # (they should always agree up to around tens-of-microseconds)
for name in names: for name in names:
floaty = int(getattr(result, name) * 100_000) with self.subTest(name=name):
nanosecondy = getattr(result, name + "_ns") // 10_000 floaty = int(getattr(result, name) * 100_000)
self.assertAlmostEqual(floaty, nanosecondy, delta=2, msg=name) nanosecondy = getattr(result, name + "_ns") // 10_000
self.assertAlmostEqual(floaty, nanosecondy, delta=2, msg=name)
def check_stat_attributes(self, fname): def check_stat_attributes(self, fname):
result = os.stat(fname) result = os.stat(fname)
@ -741,14 +742,19 @@ def test_stat_result_pickle(self):
unpickled = pickle.loads(p) unpickled = pickle.loads(p)
self.assertEqual(result, unpickled) self.assertEqual(result, unpickled)
def check_statx_attributes(self, fname): def check_statx_attributes(self, filename):
maximal_mask = 0 maximal_mask = 0
for name in dir(os): for name in dir(os):
if name.startswith('STATX_'): if name.startswith('STATX_'):
maximal_mask |= getattr(os, name) maximal_mask |= getattr(os, name)
result = os.statx(self.fname, maximal_mask) result = os.statx(filename, maximal_mask)
basic_result = os.stat(filename)
time_attributes = ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime') time_attributes = ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime')
# gh-83714: st_birthtime can be None on tmpfs even if STATX_BTIME mask
# is used
time_attributes = [name for name in time_attributes
if getattr(result, name) is not None]
self.check_timestamp_agreement(result, time_attributes) self.check_timestamp_agreement(result, time_attributes)
# Check that valid attributes match os.stat. # Check that valid attributes match os.stat.
@ -773,7 +779,6 @@ def check_statx_attributes(self, fname):
('st_rdev', 0), ('st_rdev', 0),
('st_dev', 0), ('st_dev', 0),
) )
basic_result = os.stat(self.fname)
for name, bits in requirements: for name, bits in requirements:
if result.stx_mask & bits == bits and hasattr(basic_result, name): if result.stx_mask & bits == bits and hasattr(basic_result, name):
x = getattr(result, name) x = getattr(result, name)