wheeltruth
Your tests passed. Your published wheel is missing files.
wheeltruth checks that your built wheel/sdist actually contains everything the
package needs — before your users find out the hard way.
The problem
twine check verifies your README renders. Nothing in the standard toolchain
verifies that the files made it into the artifact. Two real cases from 2026:
- MLX v0.32.0 (2026-07-25): the macOS ARM64 wheel shipped
py.typedbut silently dropped every.pyistub the previous release had. Downstream type checking broke, and the test suite never noticed — because tests run against the source tree, not the wheel. - OpenSpace (2026-06-14): a tracked
host_skills/directory vanished from the built distribution, breaking integrations for everyone who installed it.
Build backends, MANIFEST.in glitches, and package-data misconfigurations drop
files quietly. wheeltruth inspects the artifact itself — the thing PyPI
actually serves — not your repo.
Install
pip install wheeltruth
Usage
# Check one or more built artifacts
wheeltruth check dist/*
# Compare a wheel against its sdist (catches files dropped between the two)
wheeltruth check dist/mypkg-1.0-py3-none-any.whl dist/mypkg-1.0.tar.gz
# Also verify expected packages from the project config
wheeltruth check dist/* --project .
# Install into a throwaway venv and import every top-level module
wheeltruth check dist/*.whl --smoke
# Machine-readable report for CI logs / PR comments
wheeltruth check dist/* --report md
Exit code is 0 when clean, 1 when issues are found — drop it straight into CI:
- name: Build
run: python -m build
- name: Verify artifacts
run: |
pip install wheeltruth
wheeltruth check dist/*
What it checks
Wheel only
RECORDcompleteness: every file in the zip is listed, every listed file exists, and sha256 hashes/sizes match (tampered or hand-edited wheels fail).entry_points.txt: everyconsole_scripts/gui_scriptstarget resolves to a module actually inside the wheel (no moreModuleNotFoundErroron first run).- Typing stub coverage: in a typed package (ships
py.typedor.pyistubs), a compiled extension module (.so/.pyd/.dylib) with neither a.pysource nor a.pyistub is flagged — that's the case where downstream type checkers truly get nothing (the MLX case: the dropped stubs described compiled modules). Pure-Python packages withpy.typedand inline annotations are not flagged. METADATAname/version consistency with the wheel filename.
Wheel vs sdist
- Files tracked in the sdist's packages that never made it into the wheel
(the OpenSpace case), and vice versa. Handles
src/layouts and ignorestests/,docs/, etc.
With --project .
- Packages declared in
pyproject.toml/setup.cfg/setup.py(or auto-discovered) actually exist in the wheel.
With --smoke
- Installs the wheel into a throwaway venv (
--no-deps --no-index) and imports every top-level module.
Limitations (v0.2)
- v0.2 is check-only: it reports problems, it doesn't fix your build config.
- Heuristics, not proof: "expected files" are inferred from the sdist or project config. Exotic layouts may produce false positives — file an issue.
--smokeneeds a workingvenv+pipand takes a few seconds per wheel.- Stub checks are consistency checks; they can't know what the previous release shipped.
License
MIT
Metadata
Release files for wheeltruth 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wheeltruth-0.2.0.tar.gz | 18.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wheeltruth-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.8 kB
Release files / wheeltruth-0.2.0.tar.gz
| Download URL | wheeltruth-0.2.0.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5512d10e037fd54b7b23be3b34c26909ca3defc7bf401343a711ead355bfcea8
|
|
BLAKE2b-256 checksum How to use checksums |
371e3b85d6b43e6405d31a93cd3166d9ffe3dcf3544f800c5738f433c32be49b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / wheeltruth-0.2.0-py3-none-any.whl
| Download URL | wheeltruth-0.2.0-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
57431151fd3365c3a6172ba8fbd120ff8b1394e3fb6e68fc89f6f1067eef49f1
|
|
BLAKE2b-256 checksum How to use checksums |
42777ad898bb6b2b2675fd97622b50581274ab81c63c25a5c12d604be8c9668e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|