Command-Line Interface¶
A simple, correct Python build frontend.
By default, a source distribution (sdist) is built from the project root and
a binary distribution (wheel) is
built from the sdist. If this is undesirable, you can pass --sdist and/or --wheel to build distributions
independently of each other.
The positional srcdir argument also accepts a .tar.gz source distribution. Build checks the filename and the
presence of PKG-INFO, extracts the archive into a temporary directory, and runs the wheel build against the
extracted source. The default --outdir is the directory containing the archive. --sdist errors against an
archive, since the archive already is an sdist.
python -m build¶
A simple, correct Python build frontend.
By default, a source distribution (sdist) is built from the project root
and a binary distribution (wheel) is built from the sdist.
If this is undesirable, you can pass `--sdist` and/or `--wheel`
to build distributions independently of each other.
python -m build [-h] [--version] [--quiet | --verbose] [--outdir PATH]
[--sdist-extract-dir PATH] [--sdist] [--wheel] [--metadata]
[--report PATH] [--config-setting KEY=[VALUE] | --config-json JSON_STRING]
[--installer {pip,uv} | --no-isolation] [--env-dir PATH]
[--dependency-constraints-txt PATH] [--skip-dependency-check]
[srcdir]
python -m build positional arguments¶
srcdir- source directory, .tar.gz source distribution, or (with –metadata) a .whl to read metadata from (defaults to the current working directory)
python -m build global options¶
python -m build build options¶
--outdirPATH,-oPATH- output directory (defaults to{srcdir}/dist). Cannot be used together with--metadata--sdist-extract-dirPATH- extract the intermediate sdist to PATH (created if missing and kept afterwards) instead of a random temporary directory; reusing it across rebuilds gives compiler caches such as ccache/sccache a stable source path. Only affects the default (via-sdist) build and building a wheel from an sdist--sdist,-s- build a source distribution (disables the default behavior)--metadata- print out a wheel’s metadata in JSON format, building it first unless the source argument is already a .whl. Cannot be used in conjunction with--sdistor--wheel--reportPATH- write a machine-readable JSON report of the built artifacts (name, path, kind, size and SHA-256 hash) to this path. Cannot be used together with--metadata--config-settingKEY=[VALUE],-CKEY=[VALUE]- settings to pass to the backend. Multiple settings can be provided. Settings beginning with a hyphen will erroneously be interpreted as options to build if separated by a space; use--config-setting=--my-setting -C--my-other-settinginstead. A setting passed without=VALUEis given an empty value, but this form is not supported by pip; writeKEY=instead for compatibility--config-jsonJSON_STRING- settings to pass to the backend as a JSON object. This is an alternative to--config-settingthat allows complex nested structures. Cannot be used together with--config-setting
python -m build installation options¶
--installerINSTALLER- Python package installer to use (defaults to pip)--no-isolation,-n- disable building the project in an isolated virtual environment. Build dependencies must be installed separately when this option is used--env-dirPATH- create the isolated build environment at this location instead of a temporary directory. The location must be empty; it is removed on success and kept on failure so it can be inspected--dependency-constraints-txtPATH- constrain build dependencies using a constraints.txt when installing dependencies--skip-dependency-check,-x- do not check that build dependencies are installed
Isolation Behavior¶
By default build will build the package in an isolated environment, but this behavior can be disabled with
--no-isolation. When using isolation, build creates a temporary virtual environment, installs the build dependencies
specified in your pyproject.toml, runs the build, and then cleans up the environment. This ensures reproducible
builds regardless of what packages are installed in your development environment.
Pass --env-dir PATH to put the environment at a fixed location instead of a temporary directory. The location must
be empty. build removes it after a successful build and keeps it after a failure so you can inspect it. A fixed path
helps compilation caches like ccache and sccache, which treat a changed build-environment path as a new file and miss
the cache. You cannot combine --env-dir with --no-isolation.
When a build fails, --env-dir and --sdist-extract-dir keep the environment and the extracted sources for
inspection; see Debug a failed build.
Dependency Check¶
With --no-isolation, build does not install anything; it checks that the build dependencies are already present in
the interpreter running build. When a requirement is unmet it exits with an Unmet dependencies error that names the
interpreter checked and, for each requirement, the version specifier that was wanted and the version that was
found (not installed when absent):
ERROR Unmet dependencies (checked against /usr/local/bin/python3.9):
anndata>=0.7.4
wanted: >=0.7.4
found: not installed
matplotlib>=3.4 -> kiwisolver>=1.0.1
wanted: >=1.0.1
found: 1.0.0
Transitive requirements are shown as a parent -> child chain; the wanted/found lines describe the unmet
leaf. Pass --skip-dependency-check to skip this check (see Basic Usage).
Verbose Output¶
Repeating -v raises the verbosity level. Each level adds to the previous one:
-vstreams the output of the environment-creation and dependency-installation subprocesses.-vvadditionally passes-vthrough to the installer.
Regardless of verbosity, after installing the build dependencies of an isolated build, build prints a summary of the
resolved versions, one name==version per line. build reads these from the isolated environment’s installed metadata,
so they reflect what was installed rather than the specifiers in pyproject.toml:
$ python -m build --wheel
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- setuptools >= 42.0.0
* Getting build dependencies for wheel...
* Installed build dependency versions:
- setuptools==82.0.1
* Building wheel...
Successfully built mypackage-1.0.0-py3-none-any.whl
build reports this for isolated builds only; with --no-isolation build installs nothing, so inspect the active
interpreter with your installer instead (for example pip list).
Build Report¶
--report PATH writes a JSON description of the built artifacts to PATH after a successful build. The artifact
names are dynamic (they encode version, Python, ABI and platform tags), so this gives scripts and CI a stable way to
refer to the produced files instead of globbing dist/. Build writes the report to a file it controls, not to
standard output, because the build backend may write to stdout/stderr too.
$ python -m build --report build-report.json
$ twine upload $(jq -r '.artifacts[].path' build-report.json)
Note
Keep the report out of the output directory: tools commonly upload dist/* wholesale (twine upload dist/*),
and a stray non-distribution file there can break that. The write is atomic, so a reader never sees a partial file;
builds running in parallel still need a distinct PATH each to avoid overwriting one another’s report.
The schema is:
{
"version": "1.0",
"artifacts": [
{
"name": "mypackage-1.0.0.tar.gz",
"path": "dist/mypackage-1.0.0.tar.gz",
"kind": "sdist",
"size": 852,
"hashes": {
"sha256": "dbd5486e6e893663263caf84a4b87d67cc28f6963b6650f69eaa54b78e42ece4"
}
},
{
"name": "mypackage-1.0.0-py3-none-any.whl",
"path": "dist/mypackage-1.0.0-py3-none-any.whl",
"kind": "wheel",
"size": 1121,
"hashes": {
"sha256": "ef460897fdce998634efc3385aa4261b4280a2fe2ab0e08ddcacc8496658465d"
}
}
]
}
version is the schema version. Each artifact lists its name (basename), path (relative to the current
directory, mirroring --outdir), kind (sdist or wheel), size in bytes, and hashes keyed by
algorithm. --report cannot be combined with --metadata.
To inspect a wheel listed in the report, pass its path straight to --metadata: when the source argument is a
.whl file, build reads METADATA from the archive and prints it as JSON instead of building anything.
$ python -m build --report build-report.json
$ python -m build --metadata "$(jq -r '.artifacts[] | select(.kind=="wheel") | .path' build-report.json)"
Alternative CLI Script¶
A pyproject-build CLI script is also available, which is functionally identical to python -m build. This is
useful for tools like pipx that prefer direct script entry points.
$ pyproject-build
$ pyproject-build --help
Both commands accept the same options and behave identically.
Common Patterns¶
For practical usage examples and workflows, see Basic Usage.
See Also¶
Basic Usage for common workflows
Backend Configuration for passing options to backends
Environment Variables for environment variables that affect build