I run the following code with Python 2.7.5. under Windows:
import os, shutil, stat, time
with open('test.txt', 'w') as f: pass # create an arbitrary file
shutil.copy('test.txt', 'test2.txt') # copy it
shutil.copystat('test.txt', 'test2.txt') # copy its stats, too
t1 = os.lstat('test.txt').st_mtime # get the time of last modification for both files
t2 = os.lstat('test2.txt').st_mtime
print t1 # prints something like: 1371123658.54
print t2 # prints the same string, as expected: 1371123658.54
print t1 == t2 # prints False! Why?!
I expect both timestamps (=floats) to be equal (as their string representations suggest), so why does t1 == t2
evaluate to False
?
Also, I was unable to reproduce this behaviour with less code, i.e. without comparing the timestamps retrieved via os.lstat
from two different files. I have the feeling, I am missing something trivial here...
True
once in a while, but not more often than once every 10 runs.
print ("%.7f" % t1) # prints e.g. 1371126279.1365688
print ("%.7f" % t2) # prints e.g. 1371126279.1365681
This raises two new questions:
shutil.copystat
?print
rounds floats by default?!It means you should know the target OS (Windows/Linux/Mac OS X etc.) wherever you'll run the program. With the shutil module, you can automate copying both the files and folders. This module follows an optimized design.
copystat() method in Python is used to copy the permission bits, last access time, last modification time, and flags value from the given source path to given destination path. The shutil. copystat() method does not affect the file content and owner and group information.
The shutil.copy2() method is identical to shutil.copy() except that copy2() attempts to preserve file metadata as well.
The problem is with conversion between different formats during the copystat
call. This is because Windows stores file times in a fixed-point decimal format, while Python stores them in a floating-point binary format. So each time there is a conversion between the two formats, some accuracy is lost. During the copystat
call:
os.stat
converts the Windows format to Python's floating-point format. Some accuracy is lost.os.utime
is called to update the file time. this converts it back to the Windows format. Some accuracy is lost again, and the file time is not necessarily the same as the first file's.When you call os.lstat
yourself, a third inaccurate conversion is performed. Due to these conversions, the file times are not exactly the same.
The documentation for os.utime
mentions this:
Note that the exact times you set here may not be returned by a subsequent stat() call, depending on the resolution with which your operating system records access and modification times
Regarding your second question (why print
appears to show the same values for both): Converting a floating-point value to a string with str(f)
or print f
will round the value. To get a value guaranteed to be unique for different floating-point values, use print repr(f)
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With