Repository navigation
Add smithy-checksums package with Rust-backed CRC32 and CRC32C - #867
Draft
jonathan343 wants to merge 4 commits into
Draft
jonathan343 wants to merge 4 commits into
jonathan343 wants to merge 4 commits into
Conversation
Adds the smithy-checksums package, which provides the checksum algorithms Smithy clients need for flexible checksums. CRC32 and CRC32C are backed by a native Rust extension (PyO3, crc-fast) with a pure-Python fallback, and SHA-1, SHA-256, SHA-512, and MD5 come from hashlib through new(). Wheels are built by an in-tree PEP 517 backend: maturin when a Rust toolchain is available, hatchling (pure Python) otherwise. Source distributions are always built with hatchling. SMITHY_PYTHON_NATIVE_BUILD (auto, always, never) overrides the choice. If Rust is present but too old, or the native build fails, the build stops with instructions instead of silently falling back. Native wheels target abi3 for 3.12+, cp314t, and abi3t for 3.15t+. Native and pure-Python checksum objects are safe to share between threads. Repository setup: - CI builds the native extension in the main matrix, checks Rust formatting, lints, dependencies (cargo-deny), and third-party license attribution (cargo-about), builds and tests native wheels on Linux, macOS, and Windows, and tests the pure-Python wheel and an sdist install without Rust. - Adds make targets check-rust, lint-rust, and third-party-licenses. - License header checks cover .rs and .pyi files. - Dependabot updates Cargo dependencies.
Pins the toolchain used for development and CI in rust-toolchain.toml, so a new stable release can't introduce clippy lints that fail CI without a change here. Builds from a source distribution are unaffected and use the installed toolchain. CI now caches Rust builds with Swatinem/rust-cache, saving caches only on develop, and adds a job that checks each native extension builds with the minimum Rust version its Cargo.toml declares. The new jobs also get names and version comments on their pinned actions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Summary
S3's flexible checksums support CRC32, CRC32C, CRC64NVME, SHA-1, SHA-256, SHA-512, MD5, and three XXHash variants. The standard library only covers CRC32, SHA, and MD5. botocore gets the rest from
awscrt, which is an optional dependency, so those algorithms are unavailable without it. smithy-python has no checksum implementations yet, so generated clients can't support flexible checksums.This PR adds a
smithy-checksumspackage, starting with CRC32 and CRC32C. Each algorithm has a Rust implementation (PyO3 and thecrc-fastcrate, which the AWS SDK for Rust also uses) and a pure-Python fallback that gives identical results. SHA-1, SHA-256, SHA-512, and MD5 come fromhashlibthrough the samenew()entry point. The fallback means the package installs everywhere, so clients can take a hard dependency on it. Platforms with native wheels get fast checksums.The PR also sets up the repository for packages with Rust extensions: build, lint, dependency, and license checks, plus CI jobs that build and test native wheels on Linux, macOS, and Windows. Wiring checksums into generated clients is out of scope.
Example
Native wheel
Pure-Python wheel
The public API is
Checksum(a protocol thathashlibobjects also satisfy),CRC32,CRC32C,new(), andHAS_NATIVE_EXTENSION. Digests are big-endian, the byte orderx-amz-checksum-*headers base64-encode.Decisions
cargois available and hatchling (pure Python) otherwise. A separate native package couldn't be a safe hard dependency, since there's no way to require it only where a wheel exists.SMITHY_PYTHON_NATIVE_BUILD=never.cargoeven to build an sdist, and the release build doesn't have Rust.LICENSE-THIRD-PARTYis included and CI checks it's current. That file andCargo.lockare 1,224 of the 2,759 added lines.Additional Testing
Correctness is checked against independent references. Those are the standard CRC check values, the CRC32C vectors from RFC 3720 appendix B.4, and the CRT (
awscrt), which botocore uses. Native and pure are also compared against each other across 300+ input lengths:uv run pytest packages/smithy-checksums -k "known_answers or matches_crt or native_matches_pure" --no-cov -qBuilt wheels locally on macOS arm64, installed each into a fresh virtual environment, and ran the package tests against the installed wheel:
cp312-abi3cp314-cp314tcp315-abi3.abi3tThe four skips are the CRT comparisons, since those environments didn't have
awscrt.Installing from the sdist without a Rust toolchain falls back to pure Python:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.