On 19/10/2020 12:42, Steve Dower wrote:
On 15Oct2020 2239, Rob Cliffe via Python-Dev wrote:
TLDR: In os.scandir directory entries, atime is always a copy of mtime rather than the actual access time.
Correction - os.stat() updates the access time to _now_, while os.scandir() returns the last access time without updating it.
Eryk replied with a deeper explanation of the cause, but fundamentally this is what you are seeing.
Feel free to file a bug, but we'll likely only add a vague note to the docs about how Windows works here rather than changing anything. If anything, we should probably fix os.stat() to avoid updating the access time so that both functions behave the same, but that might be too complicated.
Cheers, Steve Sorry - what you say does not match the behaviour I observe, which is that (1) Neither os.stat, nor reading os.scandir directory entries, update any of the times on disk. (2) os.stat.st_atime returns the "correct" time the file was last accessed. (3) os.scandir always returns st.atime equal to st.mtime.
Modified demo program: # osscandirtest.py import time, os print(f'[1] {time.time()=}') with open('Test', 'w') as f: f.write('Anything\n') time.sleep(20) print(f'[2] {time.time()=}') with open('Test', 'r') as f: f.readline() # Read the file time.sleep(10) print(f'[3] {time.time()=}') print(os.stat('Test')) for DirEntry in os.scandir('.'): if DirEntry.name == 'Test': stat = DirEntry.stat() print(f'scandir DirEntry {stat.st_ctime=} {stat.st_mtime=} {stat.st_atime=}') print(os.stat('Test')) for DirEntry in os.scandir('.'): if DirEntry.name == 'Test': stat = DirEntry.stat() print(f'scandir DirEntry {stat.st_ctime=} {stat.st_mtime=} {stat.st_atime=}') print(f'[4] {time.time()=}') Sample output: [1] time.time()=1603166161.12121 [2] time.time()=1603166181.1306772 [3] time.time()=1603166191.1426473 os.stat_result(st_mode=33206, st_ino=9851624184951253, st_dev=2230120362, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1603166181, st_mtime=1603166161, st_ctime=1603166161) scandir DirEntry stat.st_ctime=1603166161.12121 stat.st_mtime=1603166161.12121 stat.st_atime=1603166161.12121 os.stat_result(st_mode=33206, st_ino=9851624184951253, st_dev=2230120362, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1603166181, st_mtime=1603166161, st_ctime=1603166161) scandir DirEntry stat.st_ctime=1603166161.12121 stat.st_mtime=1603166161.12121 stat.st_atime=1603166161.12121 [4] time.time()=1603166191.1426473 You will observe that (1) The results from the two os.stat calls are the same, as are the results from the two scandir calls. (2) The os.stat.st_atime (1603166181) *IS* the time that the file was read with the with open('Test', 'r') as f: f.readline() # Read the file line of code, as it matches the [2] time.time()=1603166181.1306772 line of output (apart from discarded fractions of a second) and is 20 seconds (*not* 30 seconds) after the file creation time, as expected. (3) The os.scandir atime is a copy of mtime (and in this case, of ctime as well). So it really does seem that the only thing "wrong" is that os.scandir returns atime as a copy of mtime, rather than the correct value. And since os.stat returns the "right" answer and os.scandir doesn't, it really seems that this is a bug, or at least a deficiency, in os.scandir. Demo run on Windows 10 Home version 1903 OS build 18362.1139 Python version 3.8.3 (32-bit). Best wishes Rob Cliffe