You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ZipFile.open() should not ignore compression, new file should default to today rather than 1980 #121402
When streaming, writing to a zip file, it internally creates a ZipInfo object without explicitly setting date_time, causing a timestamp of 1980 to be used. I believe in almost all cases, using the current timestamp makes more sense, I rarely zip files from 1980. To work around that issue, I create the ZipInfo object myself and pass it to the open() method, which causes another bug where the specified compression is ignored and the file is simply stored.
After some minor investigation, I've found issue #113971 which at least hinted towards what I now use as workaround but otherwise didn't fix this:
Today people pass ZipInfo instances into APIs that accept them such as ZipFile.writestr() in order to control how individual items are put into a zip archive as such ...
zip_info.compress_type
So you'd create a new ZipFile specifying a compression but after open(), you're just storing uncompressed:
In other words, I expect that:
a) when using open("file"...), it should use the current time as mtime by default
b) when creating a ZipInfo object to specify another date or another setting for the new file, it should inherit the previously configured compression
Both assumptions are wrong, which is what I'm suggesting to fix.
As for using the archive default compression by default, this is more complex question.
Please note that the second bug I'm trying to fix is not merely using a default compression (I don't want to change the default behavior) but what happens is that the programmer explicitly specifies the compression (line 8) which is then ignored when adding files (lines 20 and 26).
I'm a fan of the logic in writestr, would using that when a str filename is passed would satisfy this request I think.
+1 to this approach. This will make the patch as simple as:
--- a/Lib/zipfile/__init__.py+++ b/Lib/zipfile/__init__.py@@ -1710,9 +1710,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
# 'name' is already an info object
zinfo = name
elif mode == 'w':
- zinfo = ZipInfo(name)- zinfo.compress_type = self.compression- zinfo.compress_level = self.compresslevel+ zinfo = ZipInfo(name)._for_archive(self)
else:
# Get info object for name
zinfo = self.getinfo(name)
However the problem is that it breaks backward compatibility and I don't know if it worth. If it's not to be implemented due to backward compatibility, the behavior differences when passing a name should at least be documented.
Activity
pythongh-121402: Fix ZipFile.open() to set current time by default, a…
serhiy-storchaka commentedon Jul 10, 2024
Why do you use
ZipInfoinstead of a string if you do not set its attributes?c0xc commentedon Jul 10, 2024
That would cause the (streamed) file to be archived with a timestamp of 1980, which is the first bug.
See my example: https://gist.github.com/c0xc/b54c005b296cdf6378ce65dd4aff3fe7#file-ztest-py-L12
serhiy-storchaka commentedon Jul 10, 2024
zipuses the current timestamp when add a file from a streamed input. So I think that it is reasonable to do the same inzipfile.As for using the archive default compression by default, this is more complex question.
c0xc commentedon Jul 10, 2024
Exactly and that's what my suggested change does, see:
https://github.com/python/cpython/pull/121405/files#diff-7629293618f2b3cf8ae7daf98526226fa12f047d71645a05497e6687aae10c76R413
Please note that the second bug I'm trying to fix is not merely using a default compression (I don't want to change the default behavior) but what happens is that the programmer explicitly specifies the compression (line 8) which is then ignored when adding files (lines 20 and 26).
obfusk commentedon Aug 28, 2024
Unfortunately, embedded timestamps are the most common problem for Reproducible Builds and changing this default might have unintended consequences.
thatch commentedon May 20, 2025
I'm a fan of the logic in writestr, would using that when a str filename is passed would satisfy this request I think.
cpython/Lib/zipfile/__init__.py
Lines 1978 to 1981 in 5ab66a8
danny0838 commentedon Jun 23, 2025
@thatch
+1 to this approach. This will make the patch as simple as:
However the problem is that it breaks backward compatibility and I don't know if it worth. If it's not to be implemented due to backward compatibility, the behavior differences when passing a name should at least be documented.