Update test hash - #13
Conversation
merge commits from fork
…3aa37e also Python upgrades make zip MD5s even less stable So: b9b90449 is possible (hash the files, not the zip). f4acd55a is not a stable target
jt-traub
left a comment
There was a problem hiding this comment.
I believe you can also get a stable hash by forcing the mtime on each file in the archive (by overwriting it's mtime in a similar way as to what is done with the permissions) but that would yield a different hash than just hashing the contents which is arguably better.
This is part of why the python bugsquash is (and has always been) awful, since there are multiple ways to get a stable hash that remove the mtime dependancy but they each produce different hashes and the test will only start passing if they choose the same solution as the one used when setting up the hash.
I have no objection to changing this back to be the hash of at least one of the valid solutions (as you are doing) but I just want to call out that it's not really a global and correct in all cases fix.
The ETag sitting in the tests now is almost certainly not something you can produce on purpose. The one that is reproducible got replaced.
There have been two values:
When ETag What it actually is
2019 (02da568)
b9b90449fe17ded2c9424367f0fd147e
MD5 of the source file names plus contents (formic paths like ./f1/f1.py). Comment said "correct hash for the files, you can trust this". Still matches today on Python 3.12 and 3.14.
June 2020 (03aa37e)
f4acd55a9e25a6c7a789ddbe52bc7521
Dropped in during "Tweak test layout for easier comprehension". No comment, no code change that would yield a new digest. I could not reproduce it as a file-content hash or as a zip MD5 with frozen timestamps, write(), or writestr().
That 2020 commit only moved stubs around. It did not change zip construction. The usual explanation is that someone ran the test once, copied md5(zip_bytes) from that run, and pasted it over the trusted file hash. Zip bytes include each file's mtime, so that snapshot is tied to that machine and that moment.
Python upgrades make zip MD5s even less stable, but they are not why f4acd55a is missing:
Zip hashing was always machine-dependent. zip_file.write() stores local mtime, Unix mode (umask), and create_system. That is the bug in the README.
Zipfile itself drifted. Empty members may be stored vs deflated, ZipInfo defaults to ZIP_STORED unless you pass compress_type, ./ prefixes are normalized by write() but kept by writestr(), and 3.8+ strict_timestamps clamps dates before 1980.
The runtime moved. Alpine Python 3 (when f4acd55a was pasted) → python:3.9-bookworm (2024) → python:3.12-slim (2025). You are on 3.14 locally. Those can emit different zip bytes for the same files.
So: b9b90449 is possible (hash the files, not the zip). f4acd55a is not a stable target;