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
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/MGICSKCSTSKS36XUP6IZTXZOSGBPMQYY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to