feat: add SHA256 verification for direct downloads - #2873
Conversation
|
|
||
| # Resolve path relative to this script so writes go to the source checkout, | ||
| # not the uv-installed copy of the package. | ||
| DIR: Final[Path] = Path(__file__).parent.parent.resolve() | ||
| PYTHON_BUILD_STANDALONE_RELEASES: Final[Path] = ( | ||
| DIR / "cibuildwheel/resources/python-build-standalone-releases.json" | ||
| ) |
|
Nice; I had started a local branch to take this up recently, but I did not go as far as Copilot has done here. Could we also add SHA256 checksums for Pyodide cross-build environments? |
9da34d0 to
f925e8c
Compare
There was a problem hiding this comment.
Pull request overview
Adds SHA256 verification for direct downloads in cibuildwheel (addressing #908). Hashes are recorded in resource config files by the maintainer update scripts, then verified at download time; on mismatch, the partial file is removed and a FatalError is raised.
Changes:
download()incibuildwheel/util/file.pygains asha256keyword and verifies the hash post-download.PythonConfigurationdataclasses on macOS/Windows/iOS/Android/Pyodide and the python-build-standalone/virtualenv helpers carry and forwardsha256todownload().- Update scripts (
bin/update_pythons.py,bin/update_virtualenv.py,bin/update_python_build_standalone.py) populatesha256from upstream metadata or by streaming the download when no upstream checksum exists; resource files are repopulated accordingly.
Reviewed changes
Copilot reviewed 12 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cibuildwheel/util/file.py | Adds SHA256 verification to the central download() helper. |
| cibuildwheel/util/python_build_standalone.py | Threads sha256 through asset lookup and cached download. |
| cibuildwheel/venv.py | Passes sha256 for virtualenv.pyz download. |
| cibuildwheel/platforms/macos.py | Adds sha256 to config + install_cpython/pypy/graalpy. |
| cibuildwheel/platforms/windows.py | Adds sha256 to config + install_pypy/graalpy. |
| cibuildwheel/platforms/ios.py | Adds sha256 to config + target CPython install. |
| cibuildwheel/platforms/android.py | Adds sha256 to config + target Python install. |
| cibuildwheel/platforms/pyodide.py | Adds sha256 field to Pyodide config dataclass. |
| cibuildwheel/extra.py | Adds sha256 to PyodideXBuildEnvRelease TypedDict. |
| cibuildwheel/resources/build-platforms.toml | Populates sha256 for macOS/Windows/iOS/Android/Pyodide URL entries. |
| cibuildwheel/resources/virtualenv.toml | Adds sha256 for the default virtualenv.pyz. |
| cibuildwheel/resources/python-build-standalone-releases.json | Bumps tag to 20260510 and adds sha256 per asset. |
| bin/update_pythons.py | Sources SHA256 from CPython API / GraalPy sidecars; falls back to streaming hash. |
| bin/update_virtualenv.py | Computes/stores SHA256 when missing or version bumped. |
| bin/update_python_build_standalone.py | Parses SHA256SUMS and writes per-asset checksums; resolves output path relative to checkout. |
| docs/_internal/pyodide-maintenance.md | Updates Pyodide config example to include sha256. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f925e8c to
4040326
Compare
|
LGTM as far as Android is concerned. |
mhsmith
left a comment
There was a problem hiding this comment.
Although, if the hashes are guaranteed to be present in build-platforms.toml, shouldn't we make them required at runtime? Otherwise, if a change to update_pythons accidentally removes the hashes in the future, we would silently lose the security.
This applies to all platforms.
148feb7 to
a62886d
Compare
| # Resolve path relative to this script so writes go to the source checkout, | ||
| # not the uv-installed copy of the package. |
There was a problem hiding this comment.
I was just thinking about this yesterday when I found that [tool.uv.sources] isn't getting recognised in the PEP 723 metadata. Probably a good follow-up for nox's codebase; just noting it here.
There was a problem hiding this comment.
I believe this is working as intended, this is a uv-specific field and would any be read by uv run, not nox?
There was a problem hiding this comment.
We could require uv then use uv run inside nox.
There was a problem hiding this comment.
Oh, what I meant was that nox itself could probably use this and delegate to uv run to run the scripts if nox[uv] is installed. More of a feature request, not a bug. Pretty sure I have a recent local branch lingering around somewhere for this; I'll put together a PR in nox a bit to elaborate.
Store SHA256 hashes when running update scripts and verify them
when downloading files at build time. This improves security by
detecting unexpected changes to downloaded artifacts.
Platforms covered: macOS (CPython, PyPy, GraalPy), iOS, Android,
virtualenv, and python-build-standalone. Windows (nuget) and
Linux (Docker) are excluded.
SHA256 sources per platform:
- macOS/iOS/Android CPython (python.org): sha256_sum from API
- GraalPy: .sha256 sidecar assets from GitHub releases
- python-build-standalone: SHA256SUMS file in release
- PyPy, BeeWare iOS, Maven (Chaquopy): stream-download and compute
Changes:
- cibuildwheel/util/file.py: add sha256 param to download()
- cibuildwheel/platforms/{macos,ios,android}.py: add sha256 to
PythonConfiguration and pass to download()
- cibuildwheel/venv.py: read sha256 from toml and pass to download()
- cibuildwheel/util/python_build_standalone.py: add sha256 to
PythonBuildStandaloneAsset and pass to download()
- cibuildwheel/resources/build-platforms.toml: add sha256 fields
- cibuildwheel/resources/virtualenv.toml: add sha256 field
- cibuildwheel/resources/python-build-standalone-releases.json: add sha256
- bin/update_pythons.py: compute/store sha256 per source strategy
- bin/update_virtualenv.py: compute sha256 by streaming download
- bin/update_python_build_standalone.py: parse SHA256SUMS file
Closes pypa#908
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: copilot-cli:claude-sonnet-4.6
…ation - Add sha256 field to Windows PythonConfiguration (PyPy/GraalPy have direct download URLs on Windows too) - Pass sha256 to install_pypy() and install_graalpy() in windows.py - Fix update_pythons.py: handle empty sha256 from CPython API (older versions) by streaming download to compute it; fix condition to check 'not sha256' rather than 'not in dict' - Fix update_virtualenv.py: compute sha256 even when version unchanged but sha256 is empty (first-time population) - Fix update_python_build_standalone.py: resolve file path relative to the script itself (not the installed package) so writes go to source checkout, not the uv cache - Populate actual sha256 values by running all three update scripts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: copilot-cli:claude-sonnet-4.6
Assisted-by: CopilotCLI:gpt-5.3-codex Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: henryiii <4616906+henryiii@users.noreply.github.com> Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Require sha256 for URL-backed Python and virtualenv download configs. Update the GraalPy updater to refresh macOS x86_64 entries by selecting the latest release that still has a matching asset, and fill the two missing GraalPy checksums in build-platforms.toml. Assisted-by: CopilotCLI:gpt-5.4
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Merge pyodide_test.py and python_build_standalone_test.py into a single unit_test/test_sha256.py since both test sha256-related behaviour. Assisted-by: opencode:glm-5
4e5804f to
219e188
Compare
🤖 Human guided, AI assisted PR (using this skill). AI text below. 🤖
Summary
Implements SHA256 checksum verification for direct downloads in cibuildwheel, addressing #908. SHA256 hashes are stored in resource config files when running maintainer update scripts, and verified at download time to detect unexpected changes to artifacts.
What changed
Runtime verification
cibuildwheel/util/file.py:download()now acceptssha256: str | None = None; verifies hash after download and raisesFatalErroron mismatchPlatform wiring
SHA256 is now stored in
PythonConfigurationdataclasses and passed through todownload()on:virtualenv.pyzUpdate scripts
SHA256 sources vary by provider:
sha256_sumfield from the downloads API (free).sha256sidecar assets from GitHub releasesSHA256SUMSfile in the releaseResource files
All URL-bearing entries in the following files now have populated
sha256fields:cibuildwheel/resources/build-platforms.toml(macOS, iOS, Android, Windows PyPy/GraalPy)cibuildwheel/resources/virtualenv.tomlcibuildwheel/resources/python-build-standalone-releases.json(179 assets, tag 20260510)Review follow-up
sha256for URL-backed Python and virtualenv configs instead of allowing empty / missing valuesAssisted-by: copilot-cli:gpt-5.4