-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-34097: Add support for zipping files older than 1980-01-01 #8270
Conversation
Lib/test/test_zipfile.py
Outdated
# Set atime and mtime to 1970-01-01 | ||
os.utime(TESTFN, (0, 0)) | ||
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | ||
zipfp.write(TESTFN, strict_timestamps=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also test the resulting timestamp is 1980-01-01 as expected.
Doc/library/zipfile.rst
Outdated
.. versionadded:: 3.8 | ||
The *strict_timestamps* keyword argument allows zip files older | ||
than 1/1/1980 at the cost of setting the year to 1980. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please describe the argument in the main text, then just use .. versionadded:: 3.8
The *strict_timestamps* keyword argument
in the changelog. Same below.
Doc/library/zipfile.rst
Outdated
.. versionadded:: 3.8 | ||
The *strict_timestamps* keyword argument allows zip files older | ||
than 1/1/1980 at the cost of setting the year to 1980. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the international and unambiguous "ISO format" to refer to dates: 1980-01-01
.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
I have made the requested changes; please review again |
Thanks for making the requested changes! @encukou: please review the changes made to this pull request. |
Doc/library/zipfile.rst
Outdated
@@ -377,6 +377,8 @@ ZipFile Objects | |||
the new entry. Similarly, *compresslevel* will override the constructor if | |||
given. | |||
The archive must be open with mode ``'w'``, ``'x'`` or ``'a'``. | |||
The *strict_timestamps* keyword argument allows to zip files older | |||
than 1980-01-01 at the cost of setting the timestamp to 1980-01-01. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just from the doc, I don't understand if I have to set the parameter to True or False to allow years older than 1980.
@@ -484,6 +484,8 @@ def from_file(cls, filename, arcname=None): | |||
isdir = stat.S_ISDIR(st.st_mode) | |||
mtime = time.localtime(st.st_mtime) | |||
date_time = mtime[0:6] | |||
if not strict_timestamps and date_time[0] < 1980: | |||
date_time = (1980, 1, 1, 0, 0, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the largest year is 2107. Years after 2017 should also be clamped to 2017-12-31, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Lib/test/test_zipfile.py
Outdated
@@ -549,6 +549,14 @@ def test_add_file_before_1980(self): | |||
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | |||
self.assertRaises(ValueError, zipfp.write, TESTFN) | |||
|
|||
def test_add_file_before_1980_no_strict_timestamps(self): | |||
# Set atime and mtime to 1970-01-01 | |||
os.utime(TESTFN, (0, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using the real filesystem which can cause troubles, maybe you can mock os.stat() intsead of return the date that you want?
It may allow to test date after year 2107.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous test is also using this. It shouldn't be a problem then.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Doc/library/zipfile.rst
Outdated
@@ -368,7 +368,7 @@ ZipFile Objects | |||
|
|||
|
|||
.. method:: ZipFile.write(filename, arcname=None, compress_type=None, \ | |||
compresslevel=None) | |||
compresslevel=None, strict_timestamps=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to use a keyword-only parameter. Same remark for other methods and functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bikeshedding: why not just "strict_timestamp=True" (no S)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are more timestamps in the zip archive. each file has it's own.
@@ -0,0 +1,2 @@ | |||
ZipFile can zip files older than 1980-01-01 at the cost of mangling the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should mention the new timestamps parameter. And maybe explain "mangling": dates before 1980-01-01 are replaced by 1980-01-01 at 00:00.
I have made the requested changes; please review again. |
Doc/library/zipfile.rst
Outdated
The *strict_timestamps* keyword argument, when set to ``False``, allows to | ||
zip files older than 1980-01-01 at the cost of setting the | ||
timestamp to 1980-01-01. | ||
Same behavior occures with files older than 2107-12-31. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not the same behavior, it is not set to 1980-01-01 in that case, but rather to 2107-12-31.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like: "Similar behavior occurs with files older newer than 2107-12-31, the timestamp is also set to the limit."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
I have also noticed I have 'older' where 'newer' should be.
Doc/library/zipfile.rst
Outdated
The *strict_timestamps* keyword argument, when set to ``False``, allows to | ||
zip files older than 1980-01-01 at the cost of setting the | ||
timestamp to 1980-01-01. | ||
Same behavior occures with files older than 2107-12-31. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, the new code now looks better! A few more comments.
Doc/library/zipfile.rst
Outdated
@@ -400,6 +404,9 @@ ZipFile Objects | |||
a closed ZipFile will raise a :exc:`ValueError`. Previously, | |||
a :exc:`RuntimeError` was raised. | |||
|
|||
.. versionadded:: 3.8 | |||
The *strict_timestamps* keyword argument |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: you may write "keyword-only", and also add a final dot.
Doc/library/zipfile.rst
Outdated
@@ -551,11 +559,19 @@ file: | |||
If *arcname* is not specified, the name will be the same as *filename*, but | |||
with any drive letter and leading path separators removed. | |||
|
|||
The *strict_timestamps* keyword argument, when set to ``False``, allows to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that it's needed to repeat here that it's a keyword argument, just write "argument".
Lib/test/test_zipfile.py
Outdated
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | ||
self.assertRaises(struct.error, zipfp.write, TESTFN) | ||
|
||
def test_add_file_after_2107_no_strict_timestamps(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO you can move this test inside test_add_file_after_2107(), no need to have two different tests.
Lib/test/test_zipfile.py
Outdated
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | ||
zipfp.write(TESTFN, strict_timestamps=False) | ||
zinfo = zipfp.getinfo(TESTFN) | ||
self.assertEqual(zinfo.date_time, (1980, 1, 1, 0, 0, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would help to also make sure that you can add error when using strict_timestamps=True here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I would prefer to be the tests modified for my proposal.
@@ -484,6 +484,8 @@ def from_file(cls, filename, arcname=None): | |||
isdir = stat.S_ISDIR(st.st_mode) | |||
mtime = time.localtime(st.st_mtime) | |||
date_time = mtime[0:6] | |||
if not strict_timestamps and date_time[0] < 1980: | |||
date_time = (1980, 1, 1, 0, 0, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Lib/test/test_zipfile.py
Outdated
os.utime(TESTFN, (4386268800, 4386268800)) | ||
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | ||
self.assertRaises(struct.error, zipfp.write, TESTFN) | ||
zipfp.write(TESTFN, strict_timestamps=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to reopen the file for the second test, since it's hard to guess what happens when on error occurs. I prefer to limit side effets of unit tests.
Lib/test/test_zipfile.py
Outdated
@@ -548,6 +548,18 @@ def test_add_file_before_1980(self): | |||
os.utime(TESTFN, (0, 0)) | |||
with zipfile.ZipFile(TESTFN2, "w") as zipfp: | |||
self.assertRaises(ValueError, zipfp.write, TESTFN) | |||
zipfp.write(TESTFN, strict_timestamps=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to reopen the file for the second test, since it's hard to guess what happens when on error occurs. I prefer to limit side effets of unit tests.
This pull request adds a new option for zipping files older than 1980-01-01.
The user has to explicitly opt in by passing a keyword strict_timestamps=False to the ZipFile.write() method. This option will zip the file at the cost of setting the file timestamp to 1980-01-01 if older than zip limit.
https://bugs.python.org/issue34097