Skip to content

Commit c9ec177

Browse files
ctrlaltf2blurb-it[bot]emmatypingjaraco
authored andcommitted
gh-134261: ZipFile - Don't rely on local time for reproducible builds & tests (GH-134264)
--------- (cherry picked from commit 9dcf94e) Co-authored-by: Caleb <23644849+ctrlaltf2@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Emma Smith <emma@emmatyping.dev> Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
1 parent accfbb6 commit c9ec177

3 files changed

Lines changed: 16 additions & 11 deletions

File tree

Lib/test/test_zipfile/test_core.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,11 +1886,8 @@ def test_write_with_source_date_epoch(self):
18861886

18871887
with zipfile.ZipFile(TESTFN, "r") as zf:
18881888
zip_info = zf.getinfo("test_source_date_epoch.txt")
1889-
get_time = time.localtime(int(os.environ['SOURCE_DATE_EPOCH']))[:6]
1890-
# Compare each element of the date_time tuple
1891-
# Allow for a 1-second difference
1892-
for z_time, g_time in zip(zip_info.date_time, get_time):
1893-
self.assertAlmostEqual(z_time, g_time, delta=1)
1889+
expected_utc = (2025, 1, 1, 7, 19, 58)
1890+
self.assertEqual(zip_info.date_time, expected_utc)
18941891

18951892
def test_write_without_source_date_epoch(self):
18961893
with os_helper.EnvironmentVarGuard() as env:
@@ -1901,9 +1898,13 @@ def test_write_without_source_date_epoch(self):
19011898

19021899
with zipfile.ZipFile(TESTFN, "r") as zf:
19031900
zip_info = zf.getinfo("test_no_source_date_epoch.txt")
1904-
current_time = time.localtime()[:6]
1905-
for z_time, c_time in zip(zip_info.date_time, current_time):
1906-
self.assertAlmostEqual(z_time, c_time, delta=2)
1901+
self.assertTimestampAlmostEqual(time.localtime(), zip_info.date_time, tolerance=2)
1902+
1903+
def assertTimestampAlmostEqual(self, time1, time2, tolerance):
1904+
import datetime
1905+
dt1 = datetime.datetime(*time1[:6])
1906+
dt2 = datetime.datetime(*time2[:6])
1907+
self.assertLessEqual((dt1 - dt2).total_seconds(), tolerance)
19071908

19081909
def test_close(self):
19091910
"""Check that the zipfile is closed after the 'with' block."""

Lib/zipfile/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,12 @@ def _for_archive(self, archive):
663663
Return self.
664664
"""
665665
# gh-91279: Set the SOURCE_DATE_EPOCH to a specific timestamp
666-
epoch = os.environ.get('SOURCE_DATE_EPOCH')
667-
get_time = int(epoch) if epoch else time.time()
668-
self.date_time = time.localtime(get_time)[:6]
666+
source_date_epoch = os.environ.get('SOURCE_DATE_EPOCH')
667+
668+
if source_date_epoch:
669+
self.date_time = time.gmtime(int(source_date_epoch))[:6]
670+
else:
671+
self.date_time = time.localtime(time.time())[:6]
669672

670673
self.compress_type = archive.compression
671674
self.compress_level = archive.compresslevel
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
zip: On reproducible builds, ZipFile uses UTC instead of the local time when writing file datetimes to avoid underflows.

0 commit comments

Comments
 (0)