Configuration¶
check-dist validates your Python source distributions (sdists) and wheel distributions to ensure they contain exactly the files you expect — nothing more, nothing less.
Quick start¶
Install the tool and run it from the root of your project:
pip install check-dist
check-dist
Or run it as a Python module:
python -m check_dist._cli
How it works¶
Build —
check-distbuilds an sdist and a wheel using build.List — It lists every file inside each archive.
VCS comparison — For the sdist, it compares the contents against files tracked by version control (currently git), taking into account any
[tool.hatch.build.targets.sdist]configuration inpyproject.toml.Present / absent checks — It verifies that files matching your
presentpatterns exist and files matching yourabsentpatterns do not, for both the sdist and the wheel.Platform extension checks — It flags files that use a shared-library extension from another platform (e.g. a
.soinside a Windows wheel).
pyproject.toml configuration¶
All configuration lives under the [tool.check-dist] table, split into sdist and wheel sub-tables.
[tool.check-dist.sdist]¶
Key |
Type |
Description |
|---|---|---|
|
list of strings |
Patterns that must match at least one file in the sdist. |
|
list of strings |
Patterns that must not match any file in the sdist. |
[tool.check-dist.wheel]¶
Key |
Type |
Description |
|---|---|---|
|
list of strings |
Patterns that must match at least one file in the wheel. |
|
list of strings |
Patterns that must not match any file in the wheel. |
Example¶
[tool.check-dist.sdist]
present = [
"my_package",
"LICENSE",
"pyproject.toml",
"README.md",
]
absent = [
".gitignore",
".copier-answers.yaml",
"Makefile",
".github",
"dist",
"docs",
]
[tool.check-dist.wheel]
present = [
"my_package",
"LICENSE",
]
absent = [
".gitignore",
".copier-answers.yaml",
"Makefile",
"pyproject.toml",
".github",
"dist",
"docs",
]
Pattern syntax¶
Patterns in present and absent lists support several matching modes:
Pattern |
Matches |
|---|---|
|
A file named exactly |
|
Any file whose path starts with |
|
Any file ending in |
|
|
|
Any file under |
Standard fnmatch wildcards are supported: *, ?, [seq], [!seq].
Platform-aware extension handling¶
check-dist automatically translates shared-library extensions across platforms so you can write a single configuration that works everywhere.
Written in config |
Linux |
macOS |
Windows |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In addition, if a file with a wrong extension for the current platform appears in a distribution (e.g. a .so file in a Windows wheel), check-dist will raise an error.
Hatch build integration¶
When your project uses Hatch as the build backend,
check-dist reads [tool.hatch.build.targets.sdist] to decide which VCS-tracked files are expected in the sdist. For example, if your configuration says:
[tool.hatch.build.targets.sdist]
packages = ["my_package"]
then only files under my_package/ are expected in the sdist, and VCS-tracked files outside those packages will not be flagged as missing.
The only-include directive is also supported:
[tool.hatch.build.targets.sdist]
only-include = [
"my_package",
"rust",
"src",
"Cargo.toml",
"Cargo.lock",
]
exclude = ["target"]
This tells check-dist that the sdist should contain files from the listed paths, minus any excluded patterns.
Note: Hatchling force-includes VCS exclusion files (e.g.
.gitignore) in sdists regardless of exclude rules. Do not add.gitignoreto yourabsentlist for sdist checks.
Copier template defaults¶
If your project was scaffolded with a Copier template and has a .copier-answers.yaml file at the root, check-dist can derive sensible present/absent defaults automatically — no [tool.check-dist] section required.
This works when the answers file contains both:
project_name— used to derive the Python module name (spaces and hyphens become underscores).add_extension— the extension type added by the template.
Supported extension types: cpp, rust, js, jupyter, rustjswasm, cppjswasm.
For example, given:
# .copier-answers.yaml
project_name: python template rust
add_extension: rust
check-dist will automatically check for Cargo.toml, rust/, python_template_rust/, etc., in the sdist, and ensure build artefacts like target/ are absent.
An explicit
[tool.check-dist]section inpyproject.tomlalways takes precedence over copier defaults. If you need to override or fine-tune the derived patterns, add your own configuration.
CLI reference¶
usage: check-dist [-h] [--no-isolation] [-v] [--pre-built DIR] [source_dir]
Check Python source and wheel distributions for correctness
positional arguments:
source_dir Source directory (default: current directory)
options:
-h, --help show this help message and exit
--no-isolation Disable build isolation
-v, --verbose List every file inside each distribution
--pre-built DIR Use existing dist files from DIR instead of building
The --pre-built flag is useful when you have an existing build pipeline
that produces the sdist and wheel (e.g. projects with complex native
toolchains like Rust + WASM or C++ + Emscripten). Point it at the
directory containing the .tar.gz and .whl files:
check-dist --pre-built dist/
If only one distribution type can be built (e.g. the wheel fails due to a
missing native compiler), check-dist will still run checks on whichever
dist was produced and warn about the failed build.
Exit codes¶
Code |
Meaning |
|---|---|
0 |
All checks passed. |
1 |
One or more checks failed. |
2 |
An unexpected error occurred (e.g. build failure, git not found). |
Python API¶
You can also use check-dist programmatically:
from check_dist import check_dist
success, messages = check_dist(".", verbose=True)
for msg in messages:
print(msg)
Key functions exposed from check_dist:
check_dist(source_dir, *, no_isolation=False, verbose=False, pre_built=None)— run all checks, returns(bool, list[str]). Passpre_built="dist/"to skip building.load_config(pyproject_path, *, source_dir=None)— load[tool.check-dist]configuration, falling back to copier defaults whensource_diris provided.load_copier_config(source_dir)— load.copier-answers.yamlfrom a directory.copier_defaults(copier_config)— derivepresent/absentpatterns from copier answers.load_hatch_config(pyproject_path)— load[tool.hatch.build]configuration.list_sdist_files(path)— list files in an sdist archive.list_wheel_files(path)— list files in a wheel archive.get_vcs_files(source_dir)— list git-tracked files.translate_extension(pattern)— translate a file extension for the current platform.matches_pattern(filepath, pattern)— test whether a file matches a pattern.check_present(files, patterns, dist_type)— verify required patterns are present.check_absent(files, patterns, dist_type)— verify unwanted patterns are absent.