WASI support is tier 2.
This directory contains configuration and helpers to facilitate cross compilation of CPython to WebAssembly (WASM) using WASI. WASI builds use WASM runtimes such as wasmtime.
NOTE: If you are looking for general information about WebAssembly that is not directly related to CPython, please see https://github.com/psf/webassembly.
This directory provides a CLI for building and packaging WASI builds for distribution.
Run all commands below from the root of the CPython source checkout.
To see all the available commands, run:
python3 Platforms/WASI --helpThe python3 interpreter used to run this CLI must be a Python version that
is receiving bugfixes. This requirement does not apply to the build Python,
which the CLI builds from the source checkout.
There are some tools that must be available to successfully build.
- C compiler
make- WASI SDK
- Wasmtime (or some other WASI runtime configured via
--host-runner)
The default runner requires Wasmtime be on PATH.
The WASI SDK must be the same version as specified in config.toml. The search for the WASI SDK is done via:
--wasi-sdkCLI optionWASI_SDK_PATHenvironment variable/optwhere the WASI SDK has been unpacked from its tarball
Note that all prerequisites are included and configured appropriately in the WASI dev container image. You can download it via:
podman pull ghcr.io/python/wasicontainer:latestThe latest image contains the WASI SDK versions required by all supported
CPython branches.
The common way to get started is to first do a full build:
python3 Platforms/WASI build --quiet --logdir cross-build/logs -- --with-pydebug --config-cacheIn the end, you will end up with a "build Python" which is a local build of Python used for cross-builds. You will also have the WASI build.
Once you have the build you can run the test you want.
Bash:
"$(python3 Platforms/WASI path)/python.sh" -m test test_osFish:
set -l wasi_dir (python3 Platforms/WASI path); "$wasi_dir/python.sh" -m test test_osIf you are working on C code and need a rebuild:
python3 Platforms/WASI make-hostIn general, the devguide covers how to build and run for WASI, but we will cover some of the details here.
The simplest way to get a pydebug WASI build is:
python3 Platforms/WASI build -- --with-pydebugThis builds the build Python and the WASI build with --with-pydebug passed to
configure (as is anything that comes after --). The builds are placed in
the cross-build/ directory of the source checkout, each in a subdirectory
matching the compiler triple for the build.
You can do the two builds separately if you want:
python3 Platforms/WASI build-python -- --with-pydebug
python3 Platforms/WASI build-hostThis can be broken down even more to the separate configure and make steps:
python3 Platforms/WASI configure-build-python -- --with-pydebug
python3 Platforms/WASI make-build-python
python3 Platforms/WASI configure-host
python3 Platforms/WASI make-hostNote that configure-host figures out to do a pydebug build by looking at the
build Python.
There is a --quiet flag to redirect output from the underlying commands to a
directory. The --logdir flag controls where the log files go (which defaults
to /tmp).
python3 Platforms/WASI build --quiet --logdir cross-build/logsThe package command is used to gather all the files necessary to make a
release and place them in an archive:
python3 Platforms/WASI packageThe files are gathered into a versioned directory inside dist/ in the source
checkout. An archive containing that directory is placed alongside it in
dist/. The gathered directory includes a bin/python3.wasmtime file to ease
launching the interpreter.
If you just need to gather the files for a release, you can use the gather
command:
python3 Platforms/WASI gatherBoth package and gather require a completed build and delete the entire
existing dist/ directory before gathering files.
There is no command just to archive the gathered files.
The path command prints the location of the build Python, WASI build, or
gathered distribution files:
python3 Platforms/WASI path build-python
python3 Platforms/WASI path wasi
python3 Platforms/WASI path distWith no location argument, path defaults to wasi. The dist location
returns the versioned distribution directory inside dist/, not the top-level
dist/ directory. The build-python and wasi locations can be queried before
building; the dist location requires WASI build metadata to determine the
versioned directory name.
The clean command deletes the entire cross-build/ and dist/ directories,
including all build files, gathered distribution files, and archives:
python3 Platforms/WASI cleanTo find out where the WASI build directory is, you can run:
python3 Platforms/WASI pathFrom there, you can run the test suite.
For Bash-like shells:
make buildbottest -C "$(python3 Platforms/WASI path)"For fish:
make buildbottest -C (python3 Platforms/WASI path)There is a python.sh file in the WASI build directory, so you can also run
tests that way.
Bash:
"$(python3 Platforms/WASI path)/python.sh" -m testFish:
set -l wasi_dir (python3 Platforms/WASI path); "$wasi_dir/python.sh" -m testIf you want to test the files meant for distribution, the directory containing
the files can be found via python3 Platforms/WASI path dist and there is a
bin/python3.wasmtime shell script.
Bash:
"$(python3 Platforms/WASI path dist)/bin/python3.wasmtime" -m testFish:
set -l dist_dir (python3 Platforms/WASI path dist); "$dist_dir/bin/python3.wasmtime" -m testimport os, sys
if sys.platform == "wasi":
# Python on WASI
...
if os.name == "posix":
# WASM platforms identify as POSIX-like.
# Windows does not provide os.uname().
machine = os.uname().machine
if machine.startswith("wasm"):
# WebAssembly (wasm32, wasm64 potentially in the future)>>> import os, sys
>>> os.uname()
posix.uname_result(
sysname='wasi',
nodename='(none)',
release='0.0.0',
version='0.0.0',
machine='wasm32'
)
>>> os.name
'posix'
>>> sys.platform
'wasi'WASI SDK defines several built-in macros. You can dump a full list of built-ins
with /path/to/wasi-sdk/bin/clang -dM -E - < /dev/null.
- WebAssembly
__wasm__(also__wasm) - wasm32
__wasm32__(also__wasm32) - wasm64
__wasm64__ - WASI
__wasi__