Technical Documentation: astral-sh/python-build-standalone
โน๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference
Overview (`README.md`)
Python Build Standalone
Self-contained, portable, high-performance Python distributions.
Highlights
- High performance,
as fast or faster than other CPython distributions. - Portable, can be installed into any path.
- Self-contained, extension modules and dependencies included.
- Python 3.10-3.15.
- Standard and free-threaded builds.
- Linux, macOS, and Windows.
- Multiple platforms and architectures
supported. - Ready to use with uv or directly from
release archives.
Python Build Standalone is maintained by Astral, the team
behind uv, ruff,
and ty.
Getting started
The most common way to use these distributions is with
uv. Run a managed Python installation with:
uvx --managed-python pythonChoose a specific Python version or a free-threaded build:
uvx --managed-python [email protected]
uvx --managed-python [email protected]+freethreadedSee the documentation for more,
including running distributions
and behavior quirks.
Downloads
Prebuilt distributions are available on
GitHub Releases.
Choose an archive for your Python version, operating system, and architecture.
Most users should choose an install_only archive; full archives also contain
build artifacts for creating custom Python distributions.
See distribution archives
for details on the available formats.
Building (`docs/building.md`)
Building
A Python distribution can be built on a Linux, macOS, or Windows host.
Regardless of the operating system, uv
must be installed. Additional operating system requirements are outlined
in the following sections.
Regardless of the host, to build a Python distribution:
$ uv run --no-dev build.pyOn Linux and macOS, ./build.py can also be used; it usesuv run --no-dev via its shebang.
To build a different version of Python:
$ uv run --no-dev build.py --python cpython-3.14Various build options can be specified:
# With profile-guided optimizations (generated code should be faster)
$ uv run --no-dev build.py --options pgo
# Produce a debug build.
$ uv run --no-dev build.py --options debug
# Produce a free-threaded build without extra optimizations
$ uv run --no-dev build.py --options freethreaded+nooptDifferent platforms support different build options.uv run --no-dev build.py --help will show the available build options
and other usage information.
Linux
The host system must be x86-64 or aarch64. The execution environment must
have access to a Docker daemon (all build operations are performed in
Docker containers for isolation from the host system). Docker Buildx must
be installed and available as docker buildx.
build.py accepts a --target-triple argument to support building
for non-native targets (i.e., cross-compiling).
This option can be used to build for musl libc:
$ ./build.py --target-triple x86_64-unknown-linux-muslOr on an x86-64 host for different architectures:
$ ./build.py --target-triple armv7-unknown-linux-gnueabi
$ ./build.py --target-triple armv7-unknown-linux-gnueabihf
$ ./build.py --target-triple ppc64le-unknown-linux-gnu
$ ./build.py --target-triple riscv64-unknown-linux-gnu
$ ./build.py --target-triple s390x-unknown-linux-gnuJessie image package authentication
The build, gcc, and rust Dockerfiles includecpython-unix/base.Dockerfile. These amd64 images use Debian Jessie
for build compatibility. Cross-compilation targets also use the gcc
image for toolchain builds.
Building these images requires Docker Buildx with support for Dockerfile
1.6's ADD --checksum instruction.
The base Dockerfile pins the SHA-256 digests of the three archivedPackages.gz indexes because Jessie's archive signing keys have expired.
Docker fetches them over HTTPS and verifies their digests before APT uses
them. APT then verifies downloaded packages against the hashes in these
fixed indexes. trusted=yes permits this separate trust root;apt-get update is blocked to prevent replacing the pinned indexes with
unauthenticated metadata.
The pinned base image lacks both apt-transport-https andca-certificates. Their bootstrap download uses HTTP, authenticated by
the pinned package hashes. Once they are installed, subsequent package
downloads use HTTPS with certificate verification.
The index digests come from the SHA256 sections of the archived
Jessie Release,
Jessie updates Release, and
Jessie security Release
files. The corresponding archive key fingerprints in the digest-pinned
base image are 126C0D24BD8A2942CC7DF8AC7638D0442B90D010
for Jessie and Jessie updates, andD21169141CECD440F2EB8DDA9D6D8F6BC857C906 for Jessie security. Any change
to the snapshot or index digests requires independently authenticating the
replacement metadata.
macOS
The Xcode command-line tools must be installed./usr/bin/clang must exist.
macOS SDK headers must be installed. If you see errors such as stdio.h
not being found, try running xcode-select --install to install them.
Verify they are installed by running xcrun --show-sdk-path. It should
print something like/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
on modern versions of macOS.
The --target-triple argument can be used to build for an Intel Mac on
an arm64 (Apple Silicon) host:
$ ./build.py --target-triple x86_64-apple-darwinAdditionally, an arm64 macOS host can be used to build Linux aarch64 and x86-64
targets using Docker:
$ ./build.py --target-triple aarch64-unknown-linux-gnu
$ ./build.py --target-triple x86_64-unknown-linux-gnuThe APPLE_SDK_PATH environment variable is recognized as the path
to the Apple SDK to use. If not defined, the build will attempt to find
an SDK by running xcrun --show-sdk-path.
aarch64-apple-darwin builds require a macOS 11.0+ SDK.
It should be possible to build for aarch64-apple-darwin from
an Intel 10.15 machine (as long as the 11.0+ SDK is used).
Windows
Visual Studio 2022 (or later) is required. For x86_64-pc-windows-msvc
targets, use Visual Studio 2026 when building CPython 3.15 or newer. Thei686-pc-windows-msvc and aarch64-pc-windows-msvc targets continue
to use Visual Studio 2022.
A compatible Windows SDK is required (10.0.26100.0 as of CPython 3.10).
A git.exe must be on PATH (to clone libffi from source).
Cygwin must be installed with the autoconf, automake, libtool,
and make packages, which are required to build libffi.
Building can be done from the x64 Native Tools Command Prompt, by calling
the vcvars batch file, or by adjusting the PATH and environment variables.
You will need to specify the path to sh.exe from Cygwin:
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exeWhen using a version of Visual Studio other than 2022, the version must
be specified with the --vs option. For example, to build CPython 3.15
with Visual Studio 2026:
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exe --vs 2026 --python cpython-3.15To produce a debug build, pass --options debug or freethreaded+debug:
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exe --options debugThe artifacts carry the _d suffix of CPython's Debug configuration
(python_d.exe, python314_d.dll, _asyncio_d.pyd) and link against
the debug C runtime (ucrtbased.dll and vcruntime*d.dll). That
runtime ships with Visual Studio and is not redistributable,
so a debug distribution only runs on a machine with Visual Studio installed.
To build a 32-bit x86 binary, simply use anx86 Native Tools Command Prompt instead of x64.
Building (`docs/building.rst`)
.. _building:
======== Building
A Python distribution can be built on a Linux, macOS, or Windows host.
Regardless of the operating system, uv <https://docs.astral.sh/uv/>_
must be installed. Additional operating system requirements are outlined
in the following sections.
Regardless of the host, to build a Python distribution::
$ uv run --no-dev build.pyOn Linux and macOS, ./build.py can also be used; it usesuv run --no-dev via its shebang.
To build a different version of Python::
$ uv run --no-dev build.py --python cpython-3.14Various build options can be specified::
# With profile-guided optimizations (generated code should be faster)
$ uv run --no-dev build.py --options pgo
# Produce a debug build.
$ uv run --no-dev build.py --options debug
# Produce a free-threaded build without extra optimizations
$ uv run --no-dev build.py --options freethreaded+nooptDifferent platforms support different build options.uv run --no-dev build.py --help will show the available build options
and other usage information.
Linux
The host system must be x86-64 or aarch64. The execution environment must
have access to a Docker daemon (all build operations are performed in
Docker containers for isolation from the host system). Docker Buildx must
be installed and available as docker buildx.
build.py accepts a --target-triple argument to support building
for non-native targets (i.e., cross-compiling).
This option can be used to build for musl libc::
$ ./build.py --target-triple x86_64-unknown-linux-muslOr on an x86-64 host for different architectures::
$ ./build.py --target-triple armv7-unknown-linux-gnueabi
$ ./build.py --target-triple armv7-unknown-linux-gnueabihf
$ ./build.py --target-triple ppc64le-unknown-linux-gnu
$ ./build.py --target-triple riscv64-unknown-linux-gnu
$ ./build.py --target-triple s390x-unknown-linux-gnuJessie image package authentication
The build, gcc, and rust Dockerfiles includecpython-unix/base.Dockerfile. These amd64 images use Debian Jessie
for build compatibility. Cross-compilation targets also use the gcc
image for toolchain builds.
Building these images requires Docker Buildx with support for Dockerfile
1.6's ADD --checksum instruction.
The base Dockerfile pins the SHA-256 digests of the three archivedPackages.gz indexes because Jessie's archive signing keys have expired.
Docker fetches them over HTTPS and verifies their digests before APT uses
them. APT then verifies downloaded packages against the hashes in these
fixed indexes. trusted=yes permits this separate trust root;apt-get update is blocked to prevent replacing the pinned indexes with
unauthenticated metadata.
The pinned base image lacks both apt-transport-https andca-certificates. Their bootstrap download uses HTTP, authenticated by
the pinned package hashes. Once they are installed, subsequent package
downloads use HTTPS with certificate verification.
The index digests come from the SHA256 sections of the archivedJessie Release <https://snapshot.debian.org/archive/debian/20230322T152120Z/dists/jessie/Release>,Jessie updates Release <https://snapshot.debian.org/archive/debian/20230322T152120Z/dists/jessie-updates/Release>, andJessie security Release <https://snapshot.debian.org/archive/debian-security/20230322T152120Z/dists/jessie/updates/Release>_
files. The corresponding archive key fingerprints in the digest-pinned
base image are 126C0D24BD8A2942CC7DF8AC7638D0442B90D010
for Jessie and Jessie updates, andD21169141CECD440F2EB8DDA9D6D8F6BC857C906 for Jessie security. Any change
to the snapshot or index digests requires independently authenticating the
replacement metadata.
macOS
The Xcode command-line tools must be installed./usr/bin/clang must exist.
macOS SDK headers must be installed. If you see errors such as stdio.h
not being found, try running xcode-select --install to install them.
Verify they are installed by running xcrun --show-sdk-path. It should
print something like/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
on modern versions of macOS.
The --target-triple argument can be used to build for an Intel Mac on
an arm64 (Apple Silicon) host::
$ ./build.py --target-triple x86_64-apple-darwinAdditionally, an arm64 macOS host can be used to build Linux aarch64 and x86-64
targets using Docker::
$ ./build.py --target-triple aarch64-unknown-linux-gnu
$ ./build.py --target-triple x86_64-unknown-linux-gnuThe APPLE_SDK_PATH environment variable is recognized as the path
to the Apple SDK to use. If not defined, the build will attempt to find
an SDK by running xcrun --show-sdk-path.
aarch64-apple-darwin builds require a macOS 11.0+ SDK.
It should be possible to build for aarch64-apple-darwin from
an Intel 10.15 machine (as long as the 11.0+ SDK is used).
Windows
Visual Studio 2022 (or later) is required. For x86_64-pc-windows-msvc
targets, use Visual Studio 2026 when building CPython 3.15 or newer. Thei686-pc-windows-msvc and aarch64-pc-windows-msvc targets continue
to use Visual Studio 2022.
A compatible Windows SDK is required (10.0.26100.0 as of CPython 3.10).
A git.exe must be on PATH (to clone libffi from source).
Cygwin must be installed with the autoconf, automake, libtool,
and make packages, which are required to build libffi.
Building can be done from the x64 Native Tools Command Prompt, by calling
the vcvars batch file, or by adjusting the PATH and environment variables.
You will need to specify the path to sh.exe from Cygwin::
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exe
When using a version of Visual Studio other than 2022, the version must
be specified with the --vs option. For example, to build CPython 3.15
with Visual Studio 2026::
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exe --vs 2026 --python cpython-3.15
To produce a debug build, pass --options debug or freethreaded+debug::
$ uv run --no-dev build.py --sh c:\cygwin\bin\sh.exe --options debug
The artifacts carry the _d suffix of CPython's Debug configuration
(python_d.exe, python314_d.dll, _asyncio_d.pyd) and link against
the debug C runtime (ucrtbased.dll and vcruntime*d.dll). That
runtime ships with Visual Studio and is not redistributable <https://learn.microsoft.com/en-us/cpp/windows/determining-which-dlls-to-redistribute>_,
so a debug distribution only runs on a machine with Visual Studio installed.
To build a 32-bit x86 binary, simply use anx86 Native Tools Command Prompt instead of x64.
Distributions (`docs/distributions.md`)
Distribution Archives
This project produces tarball archives containing Python distributions.
Full Archive
The canonical output of this project's build system are .tar.zst
(zstandard compressed tarballs) files.
All files within the tar are prefixed with python/.
Within the python/ directory are the following well-known paths:
PYTHON.json
: Machine readable file describing this Python distribution.
See the `PYTHON.json File` section for the format of this file.By convention, the build/ directory contains artifacts from building
this distribution (object files, libraries, etc) and the install/ directory
contains a working, self-contained Python installation of this distribution.
The PYTHON.json file should be read to determine where specific entities
are located within the archive.
PYTHON.json File
The PYTHON.json file describes the Python distribution in a machine
readable manner. This file is meant to be opened by downstream consumers
of this distribution so that they may learn things about the distribution
without having to resort to heuristics.
The file contains a JSON map. This map has the following keys:
version
: Version number of the file format. Currently 8.
target_triple
: A target triple defining the platform and architecture of the machine
that binaries target. We use Rust's set of defined targets for values.
Run rustup target list to see potential values.
Example values are `x86_64-unknown-linux-gnu`,
`x86_64-unknown-linux-musl`, `x86_64-pc-windows-msvc`,
and `x86_64-apple-darwin`.
(Version 5 or above only.)optimizations
: String indicating what optimization profile has been applied to the
build.
Known values include `debug`, `noopt`, `pgo`, `lto`, and
`pgo+lto`.
(Deprecated in version 8 in favor of `build_options`.)build_options
: String indicating what build options were used. Options are separated
by a +.
Known values include `debug`, `noopt`, `pgo`, `lto`, `static`,
and `freethreaded`.
(Version 8 or above only.)os
: Target operating system for the distribution. e.g. linux, macos,
or windows.
(Deprecated in version 5 in favor of `target_triple`.)arch
: Target architecture for the distribution. e.g. x86 (32-bit) or
x86_64 (64-bit).
(Deprecated in version 5 in favor of `target_triple`.)python_tag
: The PEP 425 Python Tag value. e.g. cp313.
(Version 5 or above only.)python_abi_tag
: The PEP 425 ABI Tag value. e.g. cp313m.
This may be null if the distribution's platform doesn't expose the concept
of an ABI tag.
(Version 5 or above only.)python_platform_tag
: The PEP 425 Platform Tag value. e.g. linux_x86_64.
(Version 5 or above only.)python_flavor
: Type of Python distribution. e.g. cpython.
(Deprecated in version 5 in favor of PEP 425 tags.)python_implementation_cache_tag
: Tag used by import machinery to derive filenames for bytecode files.
This is the value exposed by `sys.implementation.cache_tag`
(Version 5 or above only.)python_implementation_hex_version
: Hexadecimal expression of implementation version.
This is the value exposed by `sys.implementation.hexversion`.
(Version 5 or above only.)python_implementation_name
: Name of Python implementation.
This is the value exposed by `sys.implementation.name`.
(Version 5 or above only.)python_implementation_version
: Array of version components of Python implementation.
This is the value exposed by `sys.implementation.version`.
Unlike `sys.implementation.version`, all elements are strings,
not a mix of numbers and strings.
(Version 5 or above only.)python_version
: Version of Python distribution. e.g. 3.13.0.
python_major_minor_version
: X.Y version string consisting of Python major and minor version.
(Version 5 or above only.)python_paths
: Mapping of sysconfig path names to paths in the distribution.
Keys are values like `stdlib` and `include`. Values are relative
paths within the distribution.
See <https://docs.python.org/3/library/sysconfig.html#installation-paths>
for the meaning of keys.
(Version 5 or above only.)python_paths_abstract
: Mapping of sysconfig path names with placeholder values.
See <https://docs.python.org/3/library/sysconfig.html#installation-paths>
for the meaning of keys.
This is equivalent to calling `sysconfig.get_paths(expand=False)`.
(Version 6 or above only.)python_config_vars
: Mapping of string configuration names to string values.
This is equivalent to `sysconfig.get_config_vars()` with all values
normalized to strings.
Many configuration values may represent state as it existed in the
build environment and aren't appropriate for the run-time environment
on a different system.
(Version 6 or above only.)python_exe
: Relative path to main Python interpreter executable.
python_include
: Relative path to include path for Python headers. If this path is on
the compiler's include path, #include should work.
(Deprecated in version 5 in favor of `python_paths`.)python_stdlib
: Relative path to Python's standard library (where .py and resource
files are located).
(Deprecated in version 5 in favor of `python_paths`.)python_stdlib_platform_config
: Relative path to a config- directory in the standard
library containing files used to embed Python in a binary.
This is a standard directory present in POSIX Python installations
and is not specific to this project.
The key may be absent if no platform config directory exists.
(Version 5 or above only.)python_stdlib_test_packages
: Array of strings of Python packages that define tests. (Version 4 or above
only.)
python_suffixes
: A map defining file suffixes for various Python file types. Each entry
in the map is an array of strings.
The map has the following keys.
`bytecode`
: Suffixes for bytecode modules. Corresponds to
`importlib.machinery.BYTECODE_SUFFIXES`. e.g. `[".pyc"]`.
`debug_bytecode`
: Suffixes for debug bytecode modules. Corresponds to
`importlib.machinery.DEBUG_BYTECODE_SUFFIXES`. e.g. `[".pyc"]`.
`extension`
: Suffixes for extension modules. Corresponds to
`importlib.machinery.EXTENSION_SUFFIXES`. e.g.
`[".cpython-313-x86_64-linux-gnu.so", ".abi3.so", ".so"]`.
`optimized_bytecode`
: Suffixes for optimized bytecode modules. Corresponds to
`importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES`. e.g.
`[".pyc"]`.
`source`
: Suffixes for source modules. Corresponds to
`importlib.machinery.SOURCE_SUFFIXES`. e.g. `[".py"]`.
(Version 5 or above only.)python_bytecode_magic_number
: Magic number to use for bytecode files, expressed as a hexadecimal
string.
(Version 5 or above only.)libpython_link_mode
: How libpython is linked. Values can be one of the following:
`static`
: Statically linked.
`shared`
: Dynamically linked. (A `libpythonXY` shared library will be part
of the distribution.)
(Version 5 or above only.)link_mode
: Alias of libpython_link_mode.
(Version 4 or above only. Deprecated in version 5.)python_symbol_visibility
: Defines how Python symbols are defined in binaries.
`global-default`
: (UNIX only.) Symbols are defined as *global* and have *default*
binding, making them visible outside their defining component.
`dllexport`
: (Windows only.) Symbols are exported via `__declspec(dllexport)`,
making them visible to external libraries.
(Version 5 or above only.)python_extension_module_loading
: Defines support for loading Python extension modules.
The value is an array of strings denoting support for various
loading mechanisms.
Note that downstream consumers reconstructing a new binary from
object files or a static library can alter support depending on
how that binary is linked.
The special values are as follows.
`builtin`
: Supports loading of *builtin* extension modules compiled into
the binary. (This should always be present.)
`shared-library`
: Supports loading of extension modules defined as shared
libraries. e.g. from `.so` or `.pyd` files.
(Version 5 or above only.)apple_sdk_canonical_name
: Optional canonical name of Apple SDK used to build.
Should only be present for target triples with `apple` in them.
The canonical name can be used to find a copy of this SDK on another
machine.
(Version 7 or above only.)apple_sdk_platform
: Optional name of the platform of the Apple SDK used to build.
Should only be present for target triples with `apple` in them.
e.g. `macosx`
(Version 7 or above only.)apple_sdk_version
: Optional version of the Apple SDK used to build.
Should only be present for target triples with `apple` in them.
If relinking build artifacts, ideally this exact SDK version is used.
Newer versions will likely work. Older versions or Clang toolchains
associated with older versions may not.
(Version 7 or above only.)apple_sdk_deployment_target
: Optional version of the Apple SDK deployment target used to build.
This effectively establishes a minimum version of the target operating
system this binary is purportedly compatible with.
(Version 7 or above only.)crt_features
: Describes C Runtime features/requirements for binaries.
The value is an array of strings denoting various properties.
The special string values are as follows.
`glibc-dynamic`
: Binaries link dynamically against glibc.
`glibc-max-symbol-version:N`
: Denotes the max symbol version seen in glibc versioned symbols.
This effectively advertises the oldest version of glibc that
binaries support and indirectly advertises the oldest Linux
distributions binaries can run on.
`static`
: Binaries link the CRT statically.
`vcruntime:N`
: Binaries link against the Microsoft Visual C++ Redistributable Runtime,
version `N`. `N` is a string like `140`, which denotes the
version component in a `vcruntimeXYZ.dll` file.
`libSystem`
: Binaries link against `libSystem.B.dylib`, which is the mega
library backing a lot of systems-level functionality in macOS.
(Version 5 or above only.)run_tests
: The path to a Python script to run the test harness for this
distribution.
(Version 5 or above only.)build_info
: A map describing build configuration and artifacts for this distribution.
See the `build_info Data` section below.licenses
: > Array of strings containing the license shortname identifiers from the
> SPDX license list (https://spdx.org/licenses/) for the Python distribution.
(Version 2 or above only.)license_path
: Path to a text file containing the license for this Python distribution.
(Version 2 or above only.)tcl_library_path
: Relative path to location of tcl library files. The path should be a
directory tree containing tcl files to support the tkinter extension.
This will include a subset of the library files provided by the tcl
and tk packages.
This points to the root directory containing tcl resources. Actual
tcl resources are in sub-directories underneath, as identified by
`tcl_library_paths`.
(Version 3 or above only.)tcl_library_paths
: Array of relative paths holding tcl library files relative to
tcl_library_path.
Because `tcl_library_path` can be shared with other resources
(e.g. on UNIX the path is typically `install/lib`, which holds
system libraries as well), distributions may advertise the list
of directories under `tcl_library_path` actually containing
tcl resources.
(Version 5 or above only.)build_info Data
The build_info key in the PYTHON.json file describes build artifacts
in the Python distribution. The primary goal of the data is to give downstream
distribution consumers enough details to integrate build artifacts into their
own build systems. This includes the ability to produce a Python binary with a
custom set of built-in extension modules.
This map has the following keys:
core
: A map describing the core Python distribution (essentially libpython).
objs
: An array of paths to object files constituting the Python core distribution.
Core object files are typically object files that are linked together to
create libpython.
links
: An array of linking requirement maps. (See below for data format.)
shared_lib
: Path to a shared library representing `libpython`. May not be defined.
(Version 4 or above only.)
static_lib
: Path to a static library representing `libpython`. May not be defined.
(Version 4 or above only.)
inittab_object
: Path to object file defining `_PyImport_Inittab`, which defines
built-in extension modules.
(Version 5 or above only.)
inittab_source
: Path to source code file that defines `_PyImport_Inittab`. On
CPython, this will point to a `config.c` file.
(Version 5 or above only.)
inittab_cflags
: Array of strings constituting compiler flags to use when compiling
`inittab_source`.
(Version 5 or above only.)extensions
: A map of extension names to an array of maps describing candidate extensions.
Extensions are non-core/non-essential parts of the Python distribution that
are frequently built as standalone entities.
Names in this map denote the name of the extension module.
Values are arrays of maps. Each map represents a potential candidate
providing the extension. There is frequently only a single extension
candidate. Multiple candidates can occur if there are e.g. varying
libraries an extension can be linked against to supply underlying
functionality.
Each map has the following keys:
in_core
: Boolean indicating if this extension is defined by the core distribution.
If true, object files should be in the `['core']['objs']` array, not the
`objs` array in this map.
Downstream consumers should key off this value to determine how to
assemble this extension's code into a new distribution.
This field was introduced to support Windows, where CPython's Visual
Studio project files define various extensions as part of the project
providing libpython. This is in contrast to make-based builds, where
the `Modules/Setup.*` files treat each extension as separate entities.
init_fn
: The name of the extension module initialization function for this
extension.
The string value may be `NULL`, which may need special handling by
consumers.
licenses
: Array of strings containing the license shortname identifiers from the
SPDX license list (<https://spdx.org/licenses/>).
If this field is missing, licenses are unknown. Empty array denotes no known
licenses.
The license applies to additional libraries needed by this extension, not
the extension itself, as extensions should be licensed the same as the
Python distribution.
(Version 2 or above only.)
license_path
: Paths to text files containing the licenses for this extension.
(Version 2 or above only.)
license_public_domain
: Bool indicating that the license for the extension is in the public
domain.
There is no SPDX identifier for public domain. And we want to be explicit
about something being in the public domain because of the legal implications.
(Version 2 or above only.)
links
: An array of linking requirement maps. (See below for data format.)
objs
: An array of paths to object files constituting this extension module.
required
: Boolean indicating if this extension is required to initialize the Python
interpreter.
shared_lib
: The path to a shared library defining this extension module. May not
be defined. (Version 4 or above only.)
static_lib
: The path to a static library defining this extension module. May not
be defined.
variant
: String describing this extension variant. Downstream consumers can key off
this value to choose an appropriate extension variant when there are
multiple options.object_file_format
: Denotes the data format for object files. Can be one of the following
values.
`elf`
: Standard object file format for Linux.
`llvm-bitcode:N`
: Files are LLVM bitcode produced with LLVM version `N`. e.g.
`llvm-bitcode:10.0.0`.
This variant is typically seen for builds using LTO.
`coff`
: Standard object file format for Windows.
`mach-o`
: Standard object file format for macOS.
(Version 5 or newer only.)Each entry in a links array is a map with the following keys:
name
: Name of the library being linked against.
path_static
: Path to the static version of this library, if available in the
distribution.
path_dynamic
: Path to the dynamic version of this library, if available in the
distribution.
framework
: Denotes that the link target is a macOS framework.
system
: Denotes that the link target is a system library.
System libraries are typically passed into the linker by name only and
found using default library search paths.Install Only Archive
At release time, this project produces tar files containing just the
Python installation, without the PYTHON.json or build files from
the full .tar.zst archives. These are referred to as install only
archives.
An install only archive is created by taking a .tar.zst and
rewriting python/install/* to python/*. All files not underpython/install/* are not carried forward to the install only
archive.
For each Python version, target, and threading variant, the fastest
available build is selected for the install only archive. Builds are
generally preferred in the following order: pgo+lto, pgo,lto, noopt.
An install only stripped archive is also available. This archive is
equivalent to install only, but without debug symbols, which results in a
smaller download and on-disk footprint.
For CPython 3.13 and newer, install only and install only stripped
archives are created separately for the GIL-enabled and free-threaded
variants. Free-threaded archives include freethreaded in the filename.
For musl targets, install only archives use dynamically linked builds.
Fully static musl builds are only available as full archives with+static in their build options.
For maximum compatibility, install only and install only stripped
archives use gzip compression.
Distributions (`docs/distributions.rst`)
.. _distributions:
===================== Distribution Archives
This project produces tarball archives containing Python distributions.
Full Archive
The canonical output of this project's build system are .tar.zst
(zstandard compressed tarballs) files.
All files within the tar are prefixed with python/.
Within the python/ directory are the following well-known paths:
PYTHON.json
Machine readable file describing this Python distribution.
See the PYTHON.json File section for the format of this file.
By convention, the build/ directory contains artifacts from building
this distribution (object files, libraries, etc) and the install/ directory
contains a working, self-contained Python installation of this distribution.
The PYTHON.json file should be read to determine where specific entities
are located within the archive.
PYTHON.json File
The PYTHON.json file describes the Python distribution in a machine
readable manner. This file is meant to be opened by downstream consumers
of this distribution so that they may learn things about the distribution
without having to resort to heuristics.
The file contains a JSON map. This map has the following keys:
version
Version number of the file format. Currently 8.
target_triple
A target triple defining the platform and architecture of the machine
that binaries target. We use Rust's set of defined targets for values.
Run rustup target list to see potential values.
Example values are x86_64-unknown-linux-gnu,
x86_64-unknown-linux-musl, x86_64-pc-windows-msvc,
and x86_64-apple-darwin.
(Version 5 or above only.)
optimizations
String indicating what optimization profile has been applied to the
build.
Known values include debug, noopt, pgo, lto, and
pgo+lto.
(Deprecated in version 8 in favor of build_options.)
build_options
String indicating what build options were used. Options are separated
by a +.
Known values include debug, noopt, pgo, lto, static,
and freethreaded.
(Version 8 or above only.)
os
Target operating system for the distribution. e.g. linux, macos,
or windows.
(Deprecated in version 5 in favor of target_triple.)
arch
Target architecture for the distribution. e.g. x86 (32-bit) or
x86_64 (64-bit).
(Deprecated in version 5 in favor of target_triple.)
python_tag
The PEP 425 Python Tag value. e.g. cp313.
(Version 5 or above only.)
python_abi_tag
The PEP 425 ABI Tag value. e.g. cp313m.
This may be null if the distribution's platform doesn't expose the concept
of an ABI tag.
(Version 5 or above only.)
python_platform_tag
The PEP 425 Platform Tag value. e.g. linux_x86_64.
(Version 5 or above only.)
python_flavor
Type of Python distribution. e.g. cpython.
(Deprecated in version 5 in favor of PEP 425 tags.)
python_implementation_cache_tag
Tag used by import machinery to derive filenames for bytecode files.
This is the value exposed by sys.implementation.cache_tag
(Version 5 or above only.)
python_implementation_hex_version
Hexadecimal expression of implementation version.
This is the value exposed by sys.implementation.hexversion.
(Version 5 or above only.)
python_implementation_name
Name of Python implementation.
This is the value exposed by sys.implementation.name.
(Version 5 or above only.)
python_implementation_version
Array of version components of Python implementation.
This is the value exposed by sys.implementation.version.
Unlike sys.implementation.version, all elements are strings,
not a mix of numbers and strings.
(Version 5 or above only.)
python_version
Version of Python distribution. e.g. 3.13.0.
python_major_minor_version
X.Y version string consisting of Python major and minor version.
(Version 5 or above only.)
python_paths
Mapping of sysconfig path names to paths in the distribution.
Keys are values like stdlib and include. Values are relative
paths within the distribution.
See https://docs.python.org/3/library/sysconfig.html#installation-paths
for the meaning of keys.
(Version 5 or above only.)
python_paths_abstract
Mapping of sysconfig path names with placeholder values.
See https://docs.python.org/3/library/sysconfig.html#installation-paths
for the meaning of keys.
This is equivalent to calling sysconfig.get_paths(expand=False).
(Version 6 or above only.)
python_config_vars
Mapping of string configuration names to string values.
This is equivalent to sysconfig.get_config_vars() with all values
normalized to strings.
Many configuration values may represent state as it existed in the
build environment and aren't appropriate for the run-time environment
on a different system.
(Version 6 or above only.)
python_exe
Relative path to main Python interpreter executable.
python_include
Relative path to include path for Python headers. If this path is on
the compiler's include path, #include should work.
(Deprecated in version 5 in favor of python_paths.)
python_stdlib
Relative path to Python's standard library (where .py and resource
files are located).
(Deprecated in version 5 in favor of python_paths.)
python_stdlib_platform_config
Relative path to a config- directory in the standard
library containing files used to embed Python in a binary.
This is a standard directory present in POSIX Python installations
and is not specific to this project.
The key may be absent if no platform config directory exists.
(Version 5 or above only.)
python_stdlib_test_packages
Array of strings of Python packages that define tests. (Version 4 or above
only.)
python_suffixes
A map defining file suffixes for various Python file types. Each entry
in the map is an array of strings.
The map has the following keys.
bytecode
Suffixes for bytecode modules. Corresponds to
importlib.machinery.BYTECODE_SUFFIXES. e.g. [".pyc"].
debug_bytecode
Suffixes for debug bytecode modules. Corresponds to
importlib.machinery.DEBUG_BYTECODE_SUFFIXES. e.g. [".pyc"].
extension
Suffixes for extension modules. Corresponds to
importlib.machinery.EXTENSION_SUFFIXES. e.g.
[".cpython-313-x86_64-linux-gnu.so", ".abi3.so", ".so"].
optimized_bytecode
Suffixes for optimized bytecode modules. Corresponds to
importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES. e.g.
[".pyc"].
source
Suffixes for source modules. Corresponds to
importlib.machinery.SOURCE_SUFFIXES. e.g. [".py"].
(Version 5 or above only.)
python_bytecode_magic_number
Magic number to use for bytecode files, expressed as a hexadecimal
string.
(Version 5 or above only.)
libpython_link_mode
How libpython is linked. Values can be one of the following:
static
Statically linked.
shared
Dynamically linked. (A libpythonXY shared library will be part
of the distribution.)
(Version 5 or above only.)
link_mode
Alias of libpython_link_mode.
(Version 4 or above only. Deprecated in version 5.)
python_symbol_visibility
Defines how Python symbols are defined in binaries.
global-default
(UNIX only.) Symbols are defined as global and have default
binding, making them visible outside their defining component.
dllexport
(Windows only.) Symbols are exported via __declspec(dllexport),
making them visible to external libraries.
(Version 5 or above only.)
python_extension_module_loading
Defines support for loading Python extension modules.
The value is an array of strings denoting support for various
loading mechanisms.
Note that downstream consumers reconstructing a new binary from
object files or a static library can alter support depending on
how that binary is linked.
The special values are as follows.
builtin
Supports loading of builtin extension modules compiled into
the binary. (This should always be present.)
shared-library
Supports loading of extension modules defined as shared
libraries. e.g. from .so or .pyd files.
(Version 5 or above only.)
apple_sdk_canonical_name
Optional canonical name of Apple SDK used to build.
Should only be present for target triples with apple in them.
The canonical name can be used to find a copy of this SDK on another
machine.
(Version 7 or above only.)
apple_sdk_platform
Optional name of the platform of the Apple SDK used to build.
Should only be present for target triples with apple in them.
e.g. macosx
(Version 7 or above only.)
apple_sdk_version
Optional version of the Apple SDK used to build.
Should only be present for target triples with apple in them.
If relinking build artifacts, ideally this exact SDK version is used.
Newer versions will likely work. Older versions or Clang toolchains
associated with older versions may not.
(Version 7 or above only.)
apple_sdk_deployment_target
Optional version of the Apple SDK deployment target used to build.
This effectively establishes a minimum version of the target operating
system this binary is purportedly compatible with.
(Version 7 or above only.)
crt_features
Describes C Runtime features/requirements for binaries.
The value is an array of strings denoting various properties.
The special string values are as follows.
glibc-dynamic
Binaries link dynamically against glibc.
glibc-max-symbol-version:N
Denotes the max symbol version seen in glibc versioned symbols.
This effectively advertises the oldest version of glibc that
binaries support and indirectly advertises the oldest Linux
distributions binaries can run on. static
Binaries link the CRT statically.
vcruntime:N
Binaries link against the Microsoft Visual C++ Redistributable Runtime,
version N. N is a string like 140, which denotes the
version component in a vcruntimeXYZ.dll file.
libSystem
Binaries link against libSystem.B.dylib, which is the mega
library backing a lot of systems-level functionality in macOS.
(Version 5 or above only.)
run_tests
The path to a Python script to run the test harness for this
distribution.
(Version 5 or above only.)
build_info
A map describing build configuration and artifacts for this distribution.
See the build_info Data section below.
licenses
Array of strings containing the license shortname identifiers from the
SPDX license list (https://spdx.org/licenses/) for the Python distribution.
(Version 2 or above only.)
license_path
Path to a text file containing the license for this Python distribution.
(Version 2 or above only.)
tcl_library_path
Relative path to location of tcl library files. The path should be a
directory tree containing tcl files to support the tkinter extension.
This will include a subset of the library files provided by the tcl
and tk packages.
This points to the root directory containing tcl resources. Actual
tcl resources are in sub-directories underneath, as identified by
tcl_library_paths.
(Version 3 or above only.)
tcl_library_paths
Array of relative paths holding tcl library files relative to
tcl_library_path.
Because tcl_library_path can be shared with other resources
(e.g. on UNIX the path is typically install/lib, which holds
system libraries as well), distributions may advertise the list
of directories under tcl_library_path actually containing
tcl resources.
(Version 5 or above only.)
build_info Data
The build_info key in the PYTHON.json file describes build artifacts
in the Python distribution. The primary goal of the data is to give downstream
distribution consumers enough details to integrate build artifacts into their
own build systems. This includes the ability to produce a Python binary with a
custom set of built-in extension modules.
This map has the following keys:
core
A map describing the core Python distribution (essentially libpython).
objs
An array of paths to object files constituting the Python core distribution.
Core object files are typically object files that are linked together to
create libpython. links
An array of linking requirement maps. (See below for data format.)
shared_lib
Path to a shared library representing libpython. May not be defined.
(Version 4 or above only.)
static_lib
Path to a static library representing libpython. May not be defined.
(Version 4 or above only.)
inittab_object
Path to object file defining _PyImport_Inittab, which defines
built-in extension modules.
(Version 5 or above only.) inittab_source
Path to source code file that defines _PyImport_Inittab. On
CPython, this will point to a config.c file.
(Version 5 or above only.) inittab_cflags
Array of strings constituting compiler flags to use when compiling
inittab_source.
(Version 5 or above only.)extensions
A map of extension names to an array of maps describing candidate extensions.
Extensions are non-core/non-essential parts of the Python distribution that
are frequently built as standalone entities.
Names in this map denote the name of the extension module.
Values are arrays of maps. Each map represents a potential candidate
providing the extension. There is frequently only a single extension
candidate. Multiple candidates can occur if there are e.g. varying
libraries an extension can be linked against to supply underlying
functionality.
Each map has the following keys:
in_core
Boolean indicating if this extension is defined by the core distribution.
If true, object files should be in the ``['core']['objs']`` array, not the
``objs`` array in this map.
Downstream consumers should key off this value to determine how to
assemble this extension's code into a new distribution.
This field was introduced to support Windows, where CPython's Visual
Studio project files define various extensions as part of the project
providing libpython. This is in contrast to make-based builds, where
the ``Modules/Setup.*`` files treat each extension as separate entities. init_fn
The name of the extension module initialization function for this
extension.
The string value may be ``NULL``, which may need special handling by
consumers. licenses
Array of strings containing the license shortname identifiers from the
SPDX license list (https://spdx.org/licenses/).
If this field is missing, licenses are unknown. Empty array denotes no known
licenses.
The license applies to additional libraries needed by this extension, not
the extension itself, as extensions should be licensed the same as the
Python distribution.
(Version 2 or above only.) license_path
Paths to text files containing the licenses for this extension.
(Version 2 or above only.) license_public_domain
Bool indicating that the license for the extension is in the public
domain.
There is no SPDX identifier for public domain. And we want to be explicit
about something being in the public domain because of the legal implications.
(Version 2 or above only.) links
An array of linking requirement maps. (See below for data format.)
objs
An array of paths to object files constituting this extension module.
required
Boolean indicating if this extension is required to initialize the Python
interpreter.
shared_lib
The path to a shared library defining this extension module. May not
be defined. (Version 4 or above only.)
static_lib
The path to a static library defining this extension module. May not
be defined.
variant
String describing this extension variant. Downstream consumers can key off
this value to choose an appropriate extension variant when there are
multiple options.
object_file_format
Denotes the data format for object files. Can be one of the following
values.
elf
Standard object file format for Linux.
llvm-bitcode:N
Files are LLVM bitcode produced with LLVM version N. e.g.
llvm-bitcode:10.0.0.
This variant is typically seen for builds using LTO. coff
Standard object file format for Windows.
mach-o
Standard object file format for macOS.
(Version 5 or newer only.)
Each entry in a links array is a map with the following keys:
name
Name of the library being linked against.
path_static
Path to the static version of this library, if available in the
distribution.
path_dynamic
Path to the dynamic version of this library, if available in the
distribution.
framework
Denotes that the link target is a macOS framework.
system
Denotes that the link target is a system library.
System libraries are typically passed into the linker by name only and
found using default library search paths.
Install Only Archive
At release time, this project produces tar files containing just the
Python installation, without the PYTHON.json or build files from
the full .tar.zst archives. These are referred to as install only
archives.
An install only archive is created by taking a .tar.zst and
rewriting python/install/* to python/*. All files not underpython/install/* are not carried forward to the install only
archive.
For each Python version, target, and threading variant, the fastest
available build is selected for the install only archive. Builds are
generally preferred in the following order: pgo+lto, pgo,lto, noopt.
An install only stripped archive is also available. This archive is
equivalent to install only, but without debug symbols, which results in a
smaller download and on-disk footprint.
For CPython 3.13 and newer, install only and install only stripped
archives are created separately for the GIL-enabled and free-threaded
variants. Free-threaded archives include freethreaded in the filename.
For musl targets, install only archives use dynamically linked builds.
Fully static musl builds are only available as full archives with+static in their build options.
For maximum compatibility, install only and install only stripped
archives use gzip compression.
Index (`docs/index.rst`)
Python Standalone Builds
This project produces self-contained, highly portable, high-performance
Python distributions. These Python distributions contain a fully usable,
full-featured Python installation: most extension modules from the Python
standard library are present, and their library dependencies are either
distributed with the distribution or are statically linked.
The Python distributions are built in a manner to minimize
run-time dependencies. This includes limiting the CPU instructions
that can be used and limiting the set of shared libraries required
at run-time. The goal is for the produced distribution to work on
any system for the targeted architecture.
The builds incorporate compiler optimizations such as profile-guided
optimization (PGO), link-time optimization (LTO), and, where appropriate,
BOLT post-link binary optimization. Together, these techniques improve
runtime performance while preserving portability.
The most common method of using these distributions is withuv <https://docs.astral.sh/uv/>_.
To run a particular distribution using uv::
uvx --managed-python pythonA Python version or another specifier can be included::
uvx --managed-python [email protected]
uvx --managed-python [email protected]+freethreaded.. toctree::
:maxdepth: 2
:caption: Contents:
running
building
quirks
technotes
distributions
status
Indices and tables
- :ref:
genindex - :ref:
search
Quirks (`docs/quirks.md`)
Behavior Quirks
While these Python distributions are intended to be broadly compatible
with the Python ecosystem, there are a few known behavior quirks that
affect specific environments, packages, or use cases.
If special keys do not work in the Python REPL
If you attempt to run python and the backspace key doesn't
erase characters or the arrow keys don't work as expected, this
is because the executable can't find the terminfo database.
If this happens, the Python REPL will print the following warning
message on startup:
Cannot read termcap database;
using dumb terminal settings.When you type a special key like the backspace key, this is
registered as a key press. There is special software (typicallyreadline or libedit) that most interactive programs use
that intercepts these special key presses and converts them into
special behavior, such as moving the cursor back instead of
forward. But because computer environments are different,
there needs to be some definition of how these special
behaviors are performed. This is the terminfo database.
When readline and libedit are compiled, there is
typically a hard-coded set of search locations for the
terminfo database baked into the built library. And when
you build a program (like Python) locally, you link againstreadline or libedit and get these default locations
for free.
These Python distributions compile and use their own version oflibedit to avoid a dependency on what is (or isn't) installed on
your system. This means that they do not use your system-provided
libraries for reading the terminfo database. This version oflibedit is configured to look for in locations that should work for
most OSes (specifically, /usr/share/terminfo on macOS, and/etc/terminfo, /lib/terminfo, and /usr/share/terminfo on
Linux, which should cover all major Linux distributions), but it is
possible that your environment has it somewhere else. If your OS stores
the terminfo database in an uncommon location, you can set theTERMINFO_DIRS environment variable so that libedit can find it.
For instance, you may need to do something like:
$ TERMINFO_DIRS=/uncommon/place/terminfo install/bin/python3.10
If you are running on a relatively standard OS and this does not work
out of the box, please file a bug report so we can add the location of
the terminfo database to the build.
For convenience, a relatively recent copy of the terminfo database
is distributed in the share/terminfo directory (../../share/terminfo
relative to the bin/python3 executable) in Linux distributions. Note
that ncurses and derived libraries don't know how to find this directory
since they are configured to use absolute paths to the terminfo database
and the absolute path of the Python distribution is obviously not known
at build time! So actually using this bundled terminfo database will
require custom code setting TERMINFO_DIRS before
ncurses/libedit/readline are loaded.
No tix on UNIX
Tix is an old widget library for Tcl/Tk. Python previously had a wrapper
for it in tkinter.tix, but it was deprecated in Python 3.6 (the
recommendation is to use tkinter.ttk) and removed in Python 3.13.
The macOS and Linux distributions from this project do not build and
ship Tix, even for Python versions 3.12 and below.
We had previously attempted to ship Tix support on Linux, but it was
broken and nobody reported an issue about it. The macOS distributions
from this project never shipped support for Tix. The official Python.org
macOS installers and Apple's build of Python do not ship support for
Tix, either, so this project behaves similarly to those distributions.
No `pip.exe` on Windows
The Windows distributions have pip installed however no Scripts/pip.exe,Scripts/pip3.exe, and Scripts/pipX.Y.exe files are provided because
the way these executables are built isn't portable. (It might be possible to
change how these are built to make them portable.)
To use pip, run python.exe -m pip. (It is generally a best practice to
invoke pip via python -m pip on all platforms so you can be explicit
about the python executable that pip uses.)
Linking Static Library on macOS
Python 3.10+ makes use of the __builtin_available() compiler feature.
This functionality requires a symbol from libclang_rt, which may not
be linked by default. Failure to link against libclang_rt could result
in a linker error due to an undefined symbol ___isOSVersionAtLeast.
To work around this linker failure, link against the static librarylibclang_rt..a present in the Clang installation. e.g.libclang_rt.osx.a. You can find this library by invokingclang --print-search-dirs and looking in the lib/darwin directory
under the printed libraries directory. An example path is/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a.
A copy of the libclang_rt..a from the Clang used to build
the distribution is included in the archive. However, it isn't annotated
in PYTHON.json because we're unsure if using the file with another
build/version of Clang is supported. Use at your own risk.
See https://jonnyzzz.com/blog/2018/06/05/link-error-2/ and
https://jonnyzzz.com/blog/2018/06/13/link-error-3/ for more on this topic.
Use of `libedit` on Linux
Python 3.10+ Linux distributions link against libedit (as opposed toreadline) by default, as libedit is supported on 3.10+ outside of
macOS.
Most Python builds on Linux will link against readline because readline
is the dominant library on Linux.
Some functionality may behave subtly differently as a result of our choice
to link libedit by default. (We choose libedit by default to
avoid GPL licensing requirements of readline.)
References to Build-Time Paths
The built Python distribution captures some absolute paths and other
build-time configuration in a handful of files:
- In a
_sysconfigdata_*.pyfile in the standard library. e.g.lib/python3.10/_sysconfigdata__linux_x86_64-linux-gnu.py. - In a
Makefileunder aconfig-*directory in the standard library.
e.g.lib/python3.10/config-3.10-x86_64-linux-gnu/Makefile. - In python-build-standalone's metadata file
PYTHON.json(mostly
reflected values from_sysconfigdata_*.py).
Each of these serves a different use case. But the general theme is various
aspects of the Python distribution attempt to capture how Python was built.
The most common use of these values is to facilitate compiling or linking
other software against this Python build. For example, the _sysconfigdata*
module is loaded by the sysconfig
module. sysconfig in turn is used by packaging tools like setuptools
and pip to figure out how to invoke a compiler for e.g. compiling C
extensions from source.
When installed by uv, these absolute
paths are fixed up to point to the actual location on your system where
the distribution was installed, so this quirk generally does not
affect uv users. The third-party tool sysconfigpatcher also does this and might
be helpful to use or reference if you are installing these distributions
on your own.
In particular, you may see references to our install-time paths on the
build infrastructure, e.g., /build and /install on Linux, a
particular SDK in /Applications/Xcode.app on macOS, and temporary
directories on Windows.
Also, Python reports the compiler and flags in use, just in case it is
needed to make binary-compatible extensions. On Linux, for instance, we
use our own builds of Clang and potentially some flags (warnings,
optimizations, locations of the build environment) that do not work or
apply in other environments. We try to configure Python to remove
unneeded flags and absolute paths to files in the build environment.
references to build-time paths. Python's sysconfig system requires
listing a compiler, so we leave it set to clang without the absolute
path, but you should be able to use another compiler like gcc to
compile extensions, too.
If there is a build time normalization that you think should be performed to
make distributions more portable, please file a GitHub issue.
Former quirks
The following quirks were previously listed on this page but have since
been resolved.
- "Static Linking of musl libc Prevents Extension Module Library
Loading": Starting with the 20250311 release, the default musl
distributions are dynamically linked by default, so extension modules
should work properly. Note that these now require a system-wide
installation of the musl C library. (This is present by default on
musl-based OSes like Alpine, and many glibc-based distros have amuslpackage you can safely co-install with glibc, too.) If you
specifically need a statically-linked binary, variants with the+staticbuild option are available, but these retain the quirk
that compiled extension modules (e.g.,musllinuxwheels) cannot be
loaded. - "Missing
libcrypt.so.1": The 20230507 release and earlier required
the system librarylibcrypt.so.1, which stopped being shipped by
default in several Linux distributions around 2022. Starting with the
20230726 release, this dependency is now only needed by the deprecatedcryptmodule, which only exists on Python 3.12 and lower. If you
still need this module, your OS may offer alibxcryptpackage to
provide this library. Alternatively, there are suggestions in What's
New in Python 3.13 about third-party replacements for thecrypt
module. - "Static Linking of
libX11/ Incompatibility with PyQt on Linux":
The 20220318 release and earlier exported dynamic symbols for the
internal, statically-linked build oflibX11and other libraries.
These would cause conflicts and potential crashes when using
third-party extension modules such as PyQt that load an actual sharedlibX11library (usually provided by your OS). Starting with the
20220502 release, symbols from internal dependencies are no longer
exported.
Quirks (`docs/quirks.rst`)
.. _quirks:
=============== Behavior Quirks
While these Python distributions are intended to be broadly compatible
with the Python ecosystem, there are a few known behavior quirks that
affect specific environments, packages, or use cases.
.. _quirk_backspace_key:
If special keys do not work in the Python REPL
If you attempt to run python and the backspace key doesn't
erase characters or the arrow keys don't work as expected, this
is because the executable can't find the terminfo database.
If this happens, the Python REPL will print the following warning
message on startup::
Cannot read termcap database;
using dumb terminal settings.
When you type a special key like the backspace key, this is
registered as a key press. There is special software (typicallyreadline or libedit) that most interactive programs use
that intercepts these special key presses and converts them into
special behavior, such as moving the cursor back instead of
forward. But because computer environments are different,
there needs to be some definition of how these special
behaviors are performed. This is the terminfo database.
When readline and libedit are compiled, there is
typically a hard-coded set of search locations for the
terminfo database baked into the built library. And when
you build a program (like Python) locally, you link againstreadline or libedit and get these default locations
for free.
These Python distributions compile and use their own version oflibedit to avoid a dependency on what is (or isn't) installed on
your system. This means that they do not use your system-provided
libraries for reading the terminfo database. This version oflibedit is configured to look for in locations that should work for
most OSes (specifically, /usr/share/terminfo on macOS, and/etc/terminfo, /lib/terminfo, and /usr/share/terminfo on
Linux, which should cover all major Linux distributions), but it is
possible that your environment has it somewhere else. If your OS stores
the terminfo database in an uncommon location, you can set theTERMINFO_DIRS environment variable so that libedit can find it.
For instance, you may need to do something like:
$ TERMINFO_DIRS=/uncommon/place/terminfo install/bin/python3.10
If you are running on a relatively standard OS and this does not work
out of the box, please file a bug report so we can add the location of
the terminfo database to the build.
For convenience, a relatively recent copy of the terminfo database
is distributed in the share/terminfo directory (../../share/terminfo
relative to the bin/python3 executable) in Linux distributions. Note
that ncurses and derived libraries don't know how to find this directory
since they are configured to use absolute paths to the terminfo database
and the absolute path of the Python distribution is obviously not known
at build time! So actually using this bundled terminfo database will
require custom code setting TERMINFO_DIRS before
ncurses/libedit/readline are loaded.
.. _quirk_macos_no_tix:
No tix on UNIX
Tix is an old widget library for Tcl/Tk. Python previously had a wrapper
for it in tkinter.tix, but it was deprecated in Python 3.6 (the
recommendation is to use tkinter.ttk) and removed in Python 3.13.
The macOS and Linux distributions from this project do not build and
ship Tix, even for Python versions 3.12 and below.
We had previously attempted to ship Tix support on Linux, but it was
broken and nobody reported an issue about it. The macOS distributions
from this project never shipped support for Tix. The official Python.org
macOS installers and Apple's build of Python do not ship support for
Tix, either, so this project behaves similarly to those distributions.
.. _quirk_windows_no_pip:
No ``pip.exe`` on Windows
The Windows distributions have pip installed however no Scripts/pip.exe,Scripts/pip3.exe, and Scripts/pipX.Y.exe files are provided because
the way these executables are built isn't portable. (It might be possible to
change how these are built to make them portable.)
To use pip, run python.exe -m pip. (It is generally a best practice to
invoke pip via python -m pip on all platforms so you can be explicit
about the python executable that pip uses.)
.. _quirk_macos_linking:
Linking Static Library on macOS
Python 3.10+ makes use of the __builtin_available() compiler feature.
This functionality requires a symbol from libclang_rt, which may not
be linked by default. Failure to link against libclang_rt could result
in a linker error due to an undefined symbol ___isOSVersionAtLeast.
To work around this linker failure, link against the static librarylibclang_rt..a present in the Clang installation. e.g.libclang_rt.osx.a. You can find this library by invokingclang --print-search-dirs and looking in the lib/darwin directory
under the printed libraries directory. An example path is/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a.
A copy of the libclang_rt..a from the Clang used to build
the distribution is included in the archive. However, it isn't annotated
in PYTHON.json because we're unsure if using the file with another
build/version of Clang is supported. Use at your own risk.
See https://jonnyzzz.com/blog/2018/06/05/link-error-2/ and
https://jonnyzzz.com/blog/2018/06/13/link-error-3/ for more on this topic.
.. _quirk_linux_libedit:
Use of ``libedit`` on Linux
Python 3.10+ Linux distributions link against libedit (as opposed toreadline) by default, as libedit is supported on 3.10+ outside of
macOS.
Most Python builds on Linux will link against readline because readline
is the dominant library on Linux.
Some functionality may behave subtly differently as a result of our choice
to link libedit by default. (We choose libedit by default to
avoid GPL licensing requirements of readline.)
.. _quirk_references_to_build_paths:
References to Build-Time Paths
The built Python distribution captures some absolute paths and other
build-time configuration in a handful of files:
- In a
_sysconfigdata_*.pyfile in the standard library. e.g.lib/python3.10/_sysconfigdata__linux_x86_64-linux-gnu.py. - In a
Makefileunder aconfig-*directory in the standard library.
e.g.lib/python3.10/config-3.10-x86_64-linux-gnu/Makefile. - In python-build-standalone's metadata file
PYTHON.json(mostly
reflected values from_sysconfigdata_*.py).
Each of these serves a different use case. But the general theme is various
aspects of the Python distribution attempt to capture how Python was built.
The most common use of these values is to facilitate compiling or linking
other software against this Python build. For example, the _sysconfigdata*
module is loaded by the sysconfig <https://docs.python.org/3/library/sysconfig.html>_
module. sysconfig in turn is used by packaging tools like setuptools
and pip to figure out how to invoke a compiler for e.g. compiling C
extensions from source.
When installed by uv <https://docs.astral.sh/uv/>, these absolute
paths are fixed up to point to the actual location on your system where
the distribution was installed, so this quirk generally does not
affect uv users. The third-party tool sysconfigpatcher <https://github.com/bluss/sysconfigpatcher> also does this and might
be helpful to use or reference if you are installing these distributions
on your own.
In particular, you may see references to our install-time paths on the
build infrastructure, e.g., /build and /install on Linux, a
particular SDK in /Applications/Xcode.app on macOS, and temporary
directories on Windows.
Also, Python reports the compiler and flags in use, just in case it is
needed to make binary-compatible extensions. On Linux, for instance, we
use our own builds of Clang and potentially some flags (warnings,
optimizations, locations of the build environment) that do not work or
apply in other environments. We try to configure Python to remove
unneeded flags and absolute paths to files in the build environment.
references to build-time paths. Python's sysconfig system requires
listing a compiler, so we leave it set to clang without the absolute
path, but you should be able to use another compiler like gcc to
compile extensions, too.
If there is a build time normalization that you think should be performed to
make distributions more portable, please file a GitHub issue.
.. _quirk_former:
.. _quirk_missing_libcrypt:
.. _quirk_linux_libx11:
Former quirks
The following quirks were previously listed on this page but have since
been resolved.
"Static Linking of musl libc Prevents Extension Module Library
Loading": Starting with the 20250311 release, the default musl
distributions are dynamically linked by default, so extension modules
should work properly. Note that these now require a system-wide
installation of the musl C library. (This is present by default on
musl-based OSes like Alpine, and many glibc-based distros have amuslpackage you can safely co-install with glibc, too.) If you
specifically need a statically-linked binary, variants with the+staticbuild option are available, but these retain the quirk
that compiled extension modules (e.g.,musllinuxwheels) cannot be
loaded."Missing
libcrypt.so.1": The 20230507 release and earlier required
the system librarylibcrypt.so.1, which stopped being shipped by
default in several Linux distributions around 2022. Starting with the
20230726 release, this dependency is now only needed by the deprecatedcryptmodule, which only exists on Python 3.12 and lower. If you
still need this module, your OS may offer alibxcryptpackage to
provide this library. Alternatively, there are suggestions inWhat's New in Python 3.13_ about third-party replacements for thecrypt
module."Static Linking of
libX11/ Incompatibility with PyQt on Linux":
The 20220318 release and earlier exported dynamic symbols for the
internal, statically-linked build oflibX11and other libraries.
These would cause conflicts and potential crashes when using
third-party extension modules such as PyQt that load an actual sharedlibX11library (usually provided by your OS). Starting with the
20220502 release, symbols from internal dependencies are no longer
exported.
.. _What's New in Python 3.13: https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594
Running (`docs/running.md`)
Running Distributions
Using uv
The most common method of using the prebuilt distributions from this
project is with uv. By default, uv will
download, install, and use an appropriate distribution if the system does
not provide a compatible Python installation that uv can discover. These
downloaded distributions are referred to as managed Python installations,
as compared to system Python installations. You can configure uv to
always use a managed Python installation, for example by using the--managed-python flag.
To run a particular distribution using uv:
uvx --managed-python pythonA Python version or another specifier can be included:
uvx --managed-python [email protected]
uvx --managed-python [email protected]+freethreadedThe uv documentation on
installing Python
and Python versions
provides more information and examples.
Obtaining Distributions
Prebuilt distributions are published as releases on GitHub at
https://github.com/astral-sh/python-build-standalone/releases.
Simply go to that page and find the latest release along with
its release notes.
Machines can find the latest release by querying the GitHub releases
API. Alternatively, a JSON file publishing metadata about the latest
release can be fetched from
https://raw.githubusercontent.com/astral-sh/python-build-standalone/latest-release/latest-release.json.
The JSON format is simple and hopefully self-descriptive.
Published distributions vary by their:
- Python version
- Target machine architecture
- Build configuration
- Archive flavor
The Python version is hopefully pretty obvious.
The target machine architecture defines the CPU type and operating
system the distribution runs on. We use LLVM target triples.
Distributions are produced for the following target triples:
aarch64-apple-darwin
: macOS ARM CPUs, i.e., Apple Silicon.
x86_64-apple-darwin
: macOS Intel CPUs.
x86_64-pc-windows-msvc
: Windows 64-bit Intel/AMD CPUs.
i686-pc-windows-msvc
: Windows 32-bit Intel/AMD CPUs.
aarch64-pc-windows-msvc
: Windows 64-bit ARM CPUs. Available for CPython 3.11 and newer.
x86_64-unknown-linux-gnu
: Linux 64-bit Intel/AMD CPUs linking against GNU libc.
x86_64-unknown-linux-musl
: Linux 64-bit Intel/AMD CPUs linking against musl libc.
Distributions are provided that dynamically link musl or are fully static
(`+static`). Dynamically linked distributions require musl to be installed
on the host. Fully static distributions have no shared library dependencies,
but cannot load Python `.so` extensions.aarch64-unknown-linux-*
: Similar to above except targeting Linux on ARM64 CPUs. Distributions
are provided for GNU libc, musl, and static musl.
For example, this target supports AWS Graviton EC2 instances. Many
Linux ARM devices are also `aarch64`.x86_64_v2-*
: Targets 64-bit Intel/AMD CPUs approximately newer than
Nehalem
(released in 2008).
Binaries will have SSE3, SSE4, and other CPU instructions added after the
~initial x86-64 CPUs were launched in 2003.
Binaries will crash if you attempt to run them on an older CPU not
supporting the newer instructions.x86_64_v3-*
: Targets 64-bit Intel/AMD CPUs approximately newer than
Haswell
(released in 2013) and
Excavator
(released in 2015).
Binaries will have AVX, AVX2, MOVBE and other newer CPU instructions.
Binaries will crash if you attempt to run them on an older CPU not
supporting the newer instructions.
Most x86-64 CPUs manufactured after 2013 (Intel) or 2015 (AMD) support
this microarchitecture level. An exception is Intel Atom P processors,
which Intel released in 2020 but did not include AVX.x86_64_v4-*
: Targets 64-bit Intel/AMD CPUs with some AVX-512 instructions.
Requires Intel CPUs manufactured after ~2017. But many Intel CPUs don't
have AVX-512.The x86_64_v2, x86_64_v3, and x86_64_v4 binaries usually crash
on startup when run on an incompatible CPU. We don't recommend running thex86_64_v4 builds in production because they likely don't yield a reliable
performance benefit. Unless you are executing these binaries on a CPU older
than ~2008 or ~2013, we recommend running the x86_64_v2 or x86_64_v3
binaries, as these should be slightly faster since they take advantage
of more modern CPU instructions which are more efficient. But if you want
maximum portability, stick with the baseline x86_64 builds.
armv7-unknown-linux-gnueabi
: Linux 32-bit ARM CPUs without hardware floating-point instructions,
linking against GNU libc.
This is an uncommon platform. In most cases, the hardware floating-point
target should be used. These distributions can be used on Debian's
`armel` port.armv7-unknown-linux-gnueabihf
: Linux 32-bit ARM CPUs with hardware floating-point instructions,
linking against GNU libc.
This is a common 32-bit ARM platform. Raspberry Pi model 2 and later
can use these distributions on many 32-bit Linux distributions.ppc64le-unknown-linux-gnu
: Linux 64-bit POWER8+ CPUs linking against GNU libc.
riscv64-unknown-linux-gnu
: Linux 64-bit RISC-V CPUs linking against GNU libc.
s390x-unknown-linux-gnu
: Linux 64-bit IBM Z (s390x) CPUs linking against GNU libc.
We recommend using the *-unknown-linux-gnu builds on Linux, since they
are able to load compiled Python extensions. The non-static*-unknown-linux-musl builds should be used on musl-based Linux
distributions like Alpine Linux. If you don't need to load compiled
extensions not provided by the standard library, or you are willing to
compile and link third-party extensions into a custom binary, the static*-unknown-linux-musl builds should work just fine.
The build configuration denotes how Python and its dependencies were built.
Common configurations include:
pgo+lto
: Profile-guided optimization and link-time optimization. These should be
the fastest distributions since they have the most build-time
optimizations.
pgo
: Profile-guided optimization.
Starting with CPython 3.12, BOLT is also applied alongside traditional
PGO on platforms supporting BOLT. (Currently just Linux x86-64.)lto
: Link-time optimization.
noopt
: A regular optimized build without PGO or LTO.
debug
: A debug build. No optimizations.
On Windows, a debug build links against the debug C runtime
(`ucrtbased.dll` and `vcruntime*d.dll`). That runtime ships with Visual
Studio and is not redistributable, so a Windows debug distribution only
runs on a machine with Visual Studio installed.freethreaded
: A free-threaded build, available for CPython 3.13 and newer. This
option is combined with an optimization option, such as
freethreaded+pgo+lto or freethreaded+lto.
static
: A fully static musl build. Has no shared library dependencies and
cannot load dynamically linked Python extensions.
The archive flavor denotes the content in the archive. See
Distribution Archives for more.
Casual users will likely want to use the install_only archive, as most
users do not need the build artifacts present in the full archive.
The install_only archive does not include the optimization options in
its filename. For each Python version, target, and threading variant,
it uses the fastest available build configuration.
An install_only_stripped archive is also available. This archive is
equivalent to install_only, but without debug symbols, which results
in a smaller download and on-disk footprint. For CPython 3.13 and newer,
free-threaded archives are identified by freethreaded in the filename.
Fully static musl builds are only available as full archives with+static in their build options. The install_only andinstall_only_stripped musl archives use dynamically linked builds.
Extracting Distributions
Distributions are defined as zstandard or gzip compressed tarballs.
Modern versions of tar support zstandard and you can extract
like any normal archive:
$ tar -axvf path/to/distribution.tar.zstd(The -a argument tells tar to guess the compression format by
the file extension.)
If your tar doesn't support -a (e.g. the default macOS tar),
try:
$ tar xvf path/to/distribution.tar.zstdIf you do not have tar, you can install and use the zstd
tool (typically available via a zstd or zstandard system
package):
$ zstd -d path/to/distribution.tar.zstd
$ tar -xvf path/to/distribution.tarIf you want to extract the distribution with Python, use thezstandard Python package:
import tarfile
import zstandard
with open("path/to/distribution.tar.zstd", "rb") as ifh:
dctx = zstandard.ZstdDecompressor()
with dctx.stream_reader(ifh) as reader:
with tarfile.open(mode="r|", fileobj=reader) as tf:
tf.extractall("path/to/output/directory")Runtime Requirements
Linux
The produced Linux binaries have minimal references to shared
libraries and thus can be executed on most Linux systems.
Distributions linked against glibc may reference the following shared
libraries:
- linux-vdso.so.1
- libpthread.so.0
- libdl.so.2 (required by ctypes extension)
- libutil.so.1
- librt.so.1
- libm.so.6
- libc.so.6
- ld-linux-x86-64.so.2
On Python 3.12 and earlier, the deprecated crypt module additionally
requires libcrypt.so.1.
The minimum glibc version required for most targets is 2.17. This should make
binaries compatible with the following Linux distributions:
- Fedora 21+
- RHEL/CentOS 7+
- openSUSE 13.2+
- Debian 8+ (Jessie)
- Ubuntu 14.04+
For the riscv64-unknown-linux-gnu target, the minimum glibc version is
2.28.
Distributions linked against musl do not depend on glibc. By default, musl
distributions are dynamically linked and require musl to be installed on the
host. Fully static distributions use the +static build option and have
no shared library dependencies, but cannot load dynamically linked Python
extension modules.
Windows
Windows distributions model the requirements of the official Python
distributions:
- CPython 3.14 and newer: Windows 10 or newer.
- CPython 3.13 and earlier: Windows 8.1 or newer.
Windows Server support follows the corresponding CPython release's
upstream platform policy.
Extra Python Software
Python installations have some additional software pre-installed:
- pip
- setuptools (for Python 3.11 and older)
The intent of the pre-installed software is to facilitate end-user
package installation without having to first bootstrap a packaging
tool via an insecure installation technique (such as curl | sh
patterns).
Licensing
Python and its various dependencies are governed by varied software use
licenses. This impacts the rights and requirements of downstream consumers.
Most licenses are fairly permissive. Notable exceptions to this are GDBM and
readline, which are both licensed under GPL Version 3.
We build CPython against libedit - as opposed to readline - to avoid this
GPL dependency. This requires patches on CPython < 3.10. Distribution releases
before 2023 may link against readline and are therefore subject to the GPL.
We globally disable the _gdbm extension module to avoid linking against
GDBM and introducing a GPL dependency. Distribution releases before 2023 may
link against GDBM and be subject to the GPL.
It is important to understand the licensing requirements when integrating
the output of this project into derived works. To help with this, the
JSON document describing the Python distribution contains licensing metadata
and the archive contains copies of license texts.
Reconsuming Build Artifacts
Produced Python distributions contain object files and libraries for the
built Python and its dependencies. It is possible for downstream consumers
to take these build artifacts and link them into a new binary.
Reconsuming the build artifacts this way can be a bit fragile due to
incompatibilities between the host that generated them and the target that
is consuming them.
To ensure optimal compatibility, it is highly recommended to use the same
toolchain for all operations.
This is often harder than it sounds. For example, if these build artifacts
were to be combined into a Rust binary, the version of LLVM that the Rust
compiler itself was built against can matter. As a concrete example, the
Rust 1.31 compiler will produce LLVM intrinsics that vary from intrinsics
that would be produced with LLVM/Clang 7. At linking time, you would get
errors like the following:
Intrinsic has incorrect argument type!
void (i8*, i8, i64, i1)* @llvm.memset.p0i8.i64The distributions that contain object files are useful for
embedding Python in a larger binary. See the
PyOxidizer sister project
for such a downstream repackager.
Some users of these distributions might be better served by the
PyOxy
sister project. PyOxy takes these Python distributions and adds Rust code
to enhance the functionality of the Python interpreter. The official
PyOxy release binaries are single-file executables providing
a full-featured Python interpreter.
Running (`docs/running.rst`)
.. _running:
===================== Running Distributions
Using uv
The most common method of using the prebuilt distributions from this
project is with uv <https://docs.astral.sh/uv/>_. By default, uv will
download, install, and use an appropriate distribution if the system does
not provide a compatible Python installation that uv can discover. These
downloaded distributions are referred to as managed Python installations,
as compared to system Python installations. You can configure uv to
always use a managed Python installation, for example by using the--managed-python flag.
To run a particular distribution using uv::
uvx --managed-python pythonA Python version or another specifier can be included::
uvx --managed-python [email protected]
uvx --managed-python [email protected]+freethreadedThe uv documentation oninstalling Python <https://docs.astral.sh/uv/guides/install-python/>_
and Python versions <https://docs.astral.sh/uv/concepts/python-versions/>_
provides more information and examples.
Obtaining Distributions
Prebuilt distributions are published as releases on GitHub at
https://github.com/astral-sh/python-build-standalone/releases.
Simply go to that page and find the latest release along with
its release notes.
Machines can find the latest release by querying the GitHub releases
API. Alternatively, a JSON file publishing metadata about the latest
release can be fetched from
https://raw.githubusercontent.com/astral-sh/python-build-standalone/latest-release/latest-release.json.
The JSON format is simple and hopefully self-descriptive.
Published distributions vary by their:
- Python version
- Target machine architecture
- Build configuration
- Archive flavor
The Python version is hopefully pretty obvious.
The target machine architecture defines the CPU type and operating
system the distribution runs on. We use LLVM target triples.
Distributions are produced for the following target triples:
aarch64-apple-darwin
macOS ARM CPUs, i.e., Apple Silicon.
x86_64-apple-darwin
macOS Intel CPUs.
x86_64-pc-windows-msvc
Windows 64-bit Intel/AMD CPUs.
i686-pc-windows-msvc
Windows 32-bit Intel/AMD CPUs.
aarch64-pc-windows-msvc
Windows 64-bit ARM CPUs. Available for CPython 3.11 and newer.
x86_64-unknown-linux-gnu
Linux 64-bit Intel/AMD CPUs linking against GNU libc.
x86_64-unknown-linux-musl
Linux 64-bit Intel/AMD CPUs linking against musl libc.
Distributions are provided that dynamically link musl or are fully static
(+static). Dynamically linked distributions require musl to be installed
on the host. Fully static distributions have no shared library dependencies,
but cannot load Python .so extensions.
aarch64-unknown-linux-*
Similar to above except targeting Linux on ARM64 CPUs. Distributions
are provided for GNU libc, musl, and static musl.
For example, this target supports AWS Graviton EC2 instances. Many
Linux ARM devices are also aarch64.
x86_64_v2-*
Targets 64-bit Intel/AMD CPUs approximately newer than
Nehalem <https://en.wikipedia.org/wiki/Nehalem_(microarchitecture)>_
(released in 2008).
Binaries will have SSE3, SSE4, and other CPU instructions added after the
~initial x86-64 CPUs were launched in 2003.
Binaries will crash if you attempt to run them on an older CPU not
supporting the newer instructions.
x86_64_v3-*
Targets 64-bit Intel/AMD CPUs approximately newer than
Haswell <https://en.wikipedia.org/wiki/Haswell_(microarchitecture)>_
(released in 2013) and
Excavator <https://en.wikipedia.org/wiki/Excavator_(microarchitecture)>_
(released in 2015).
Binaries will have AVX, AVX2, MOVBE and other newer CPU instructions.
Binaries will crash if you attempt to run them on an older CPU not
supporting the newer instructions.
Most x86-64 CPUs manufactured after 2013 (Intel) or 2015 (AMD) support
this microarchitecture level. An exception is Intel Atom P processors,
which Intel released in 2020 but did not include AVX.
x86_64_v4-*
Targets 64-bit Intel/AMD CPUs with some AVX-512 instructions.
Requires Intel CPUs manufactured after ~2017. But many Intel CPUs don't
have AVX-512.
The x86_64_v2, x86_64_v3, and x86_64_v4 binaries usually crash
on startup when run on an incompatible CPU. We don't recommend running thex86_64_v4 builds in production because they likely don't yield a reliable
performance benefit. Unless you are executing these binaries on a CPU older
than ~2008 or ~2013, we recommend running the x86_64_v2 or x86_64_v3
binaries, as these should be slightly faster since they take advantage
of more modern CPU instructions which are more efficient. But if you want
maximum portability, stick with the baseline x86_64 builds.
armv7-unknown-linux-gnueabi
Linux 32-bit ARM CPUs without hardware floating-point instructions,
linking against GNU libc.
This is an uncommon platform. In most cases, the hardware floating-point
target should be used. These distributions can be used on Debian's
armel port.
armv7-unknown-linux-gnueabihf
Linux 32-bit ARM CPUs with hardware floating-point instructions,
linking against GNU libc.
This is a common 32-bit ARM platform. Raspberry Pi model 2 and later
can use these distributions on many 32-bit Linux distributions.
ppc64le-unknown-linux-gnu
Linux 64-bit POWER8+ CPUs linking against GNU libc.
riscv64-unknown-linux-gnu
Linux 64-bit RISC-V CPUs linking against GNU libc.
s390x-unknown-linux-gnu
Linux 64-bit IBM Z (s390x) CPUs linking against GNU libc.
We recommend using the *-unknown-linux-gnu builds on Linux, since they
are able to load compiled Python extensions. The non-static*-unknown-linux-musl builds should be used on musl-based Linux
distributions like Alpine Linux. If you don't need to load compiled
extensions not provided by the standard library, or you are willing to
compile and link third-party extensions into a custom binary, the static*-unknown-linux-musl builds should work just fine.
The build configuration denotes how Python and its dependencies were built.
Common configurations include:
pgo+lto
Profile-guided optimization and link-time optimization. These should be
the fastest distributions since they have the most build-time
optimizations.
pgo
Profile-guided optimization.
Starting with CPython 3.12, BOLT is also applied alongside traditional
PGO on platforms supporting BOLT. (Currently just Linux x86-64.)
lto
Link-time optimization.
noopt
A regular optimized build without PGO or LTO.
debug
A debug build. No optimizations.
freethreaded
A free-threaded build, available for CPython 3.13 and newer. This
option is combined with an optimization option, such as
freethreaded+pgo+lto or freethreaded+lto.
static
A fully static musl build. Has no shared library dependencies and
cannot load dynamically linked Python extensions.
The archive flavor denotes the content in the archive. See
:ref:distributions for more.
Casual users will likely want to use the install_only archive, as most
users do not need the build artifacts present in the full archive.
The install_only archive does not include the optimization options in
its filename. For each Python version, target, and threading variant,
it uses the fastest available build configuration.
An install_only_stripped archive is also available. This archive is
equivalent to install_only, but without debug symbols, which results
in a smaller download and on-disk footprint. For CPython 3.13 and newer,
free-threaded archives are identified by freethreaded in the filename.
Fully static musl builds are only available as full archives with+static in their build options. The install_only andinstall_only_stripped musl archives use dynamically linked builds.
Extracting Distributions
Distributions are defined as zstandard or gzip compressed tarballs.
Modern versions of tar support zstandard and you can extract
like any normal archive::
$ tar -axvf path/to/distribution.tar.zstd
(The -a argument tells tar to guess the compression format by
the file extension.)
If your tar doesn't support -a (e.g. the default macOS tar),
try::
$ tar xvf path/to/distribution.tar.zstd
If you do not have tar, you can install and use the zstd
tool (typically available via a zstd or zstandard system
package)::
$ zstd -d path/to/distribution.tar.zstd
$ tar -xvf path/to/distribution.tar
If you want to extract the distribution with Python, use thezstandard Python package:
.. code-block:: python
import tarfile
import zstandard
with open("path/to/distribution.tar.zstd", "rb") as ifh:
dctx = zstandard.ZstdDecompressor()
with dctx.stream_reader(ifh) as reader:
with tarfile.open(mode="r|", fileobj=reader) as tf:
tf.extractall("path/to/output/directory")
Runtime Requirements
Linux
The produced Linux binaries have minimal references to shared
libraries and thus can be executed on most Linux systems.
Distributions linked against glibc may reference the following shared
libraries:
- linux-vdso.so.1
- libpthread.so.0
- libdl.so.2 (required by ctypes extension)
- libutil.so.1
- librt.so.1
- libm.so.6
- libc.so.6
- ld-linux-x86-64.so.2
On Python 3.12 and earlier, the deprecated crypt module additionally
requires libcrypt.so.1.
The minimum glibc version required for most targets is 2.17. This should make
binaries compatible with the following Linux distributions:
- Fedora 21+
- RHEL/CentOS 7+
- openSUSE 13.2+
- Debian 8+ (Jessie)
- Ubuntu 14.04+
For the riscv64-unknown-linux-gnu target, the minimum glibc version is
2.28.
Distributions linked against musl do not depend on glibc. By default, musl
distributions are dynamically linked and require musl to be installed on the
host. Fully static distributions use the +static build option and have
no shared library dependencies, but cannot load dynamically linked Python
extension modules.
Windows
Windows distributions model the requirements of the official Python
distributions:
- CPython 3.14 and newer: Windows 10 or newer.
- CPython 3.13 and earlier: Windows 8.1 or newer.
Windows Server support follows the corresponding CPython release's
upstream platform policy.
Extra Python Software
Python installations have some additional software pre-installed:
pip <https://pypi.org/project/pip/>_setuptools <https://pypi.org/project/setuptools/>_ (for Python 3.11 and older)
The intent of the pre-installed software is to facilitate end-user
package installation without having to first bootstrap a packaging
tool via an insecure installation technique (such as curl | sh
patterns).
Licensing
Python and its various dependencies are governed by varied software use
licenses. This impacts the rights and requirements of downstream consumers.
Most licenses are fairly permissive. Notable exceptions to this are GDBM and
readline, which are both licensed under GPL Version 3.
We build CPython against libedit - as opposed to readline - to avoid this
GPL dependency. This requires patches on CPython < 3.10. Distribution releases
before 2023 may link against readline and are therefore subject to the GPL.
We globally disable the _gdbm extension module to avoid linking against
GDBM and introducing a GPL dependency. Distribution releases before 2023 may
link against GDBM and be subject to the GPL.
It is important to understand the licensing requirements when integrating
the output of this project into derived works. To help with this, the
JSON document describing the Python distribution contains licensing metadata
and the archive contains copies of license texts.
Reconsuming Build Artifacts
Produced Python distributions contain object files and libraries for the
built Python and its dependencies. It is possible for downstream consumers
to take these build artifacts and link them into a new binary.
Reconsuming the build artifacts this way can be a bit fragile due to
incompatibilities between the host that generated them and the target that
is consuming them.
To ensure optimal compatibility, it is highly recommended to use the same
toolchain for all operations.
This is often harder than it sounds. For example, if these build artifacts
were to be combined into a Rust binary, the version of LLVM that the Rust
compiler itself was built against can matter. As a concrete example, the
Rust 1.31 compiler will produce LLVM intrinsics that vary from intrinsics
that would be produced with LLVM/Clang 7. At linking time, you would get
errors like the following::
Intrinsic has incorrect argument type!
void (i8*, i8, i64, i1)* @llvm.memset.p0i8.i64The distributions that contain object files are useful for
embedding Python in a larger binary. See thePyOxidizer <https://github.com/indygreg/PyOxidizer>_ sister project
for such a downstream repackager.
Some users of these distributions might be better served by thePyOxy <https://pyoxidizer.readthedocs.io/en/latest/pyoxy.html>_
sister project. PyOxy takes these Python distributions and adds Rust code
to enhance the functionality of the Python interpreter. The official
PyOxy release binaries are single-file executables providing
a full-featured Python interpreter.
Status (`docs/status.md`)
Project Status
There is support for producing CPython distributions for Windows,
macOS, and Linux. All distributions are highly self-contained and have
limited shared library dependencies.
Target Notes
Linux x86_64 and aarch64 targets (x86_64-* and aarch64-*) are built on
native hardware using a modern LLVM toolchain.
All other architectures are cross-compiled on x86_64 using Debian-provided
cross-compilation tools. As a result, these targets are not as highly
optimized as aarch64 and x86_64 targets.
Test Failures
This repository contains a test-distribution.py script that can be
used to run the Python test harness from a distribution archive.
Currently, this script is only used to validate a limited set of
functionality for each distribution. The entire Python test harness is
not run on a regular basis. Work is ongoing to perform this type of
testing on a regular basis.
The details below on known failing and skipped tests are out of date. In
the future, this information will be updated and presented elsewhere.
Here, we track the various known failures when runningtest-distribution.py --stdlib -- /path/to/distribution.tar.zst -u all.
`test__locale`
Known failing on: Windows
This test fails as follows:
======================================================================
ERROR: test_float_parsing (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmpjx7a33kd\python\install\lib\test\test__locale.py", line 184, in test_float_parsing
if localeconv()['decimal_point'] != '.':
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
======================================================================
ERROR: test_lc_numeric_localeconv (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmpjx7a33kd\python\install\lib\test\test__locale.py", line 130, in test_lc_numeric_localeconv
formatting = localeconv()
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
----------------------------------------------------------------------`test_locale`
Known failing on: Windows
This test fails on Windows:
======================================================================
ERROR: test_getsetlocale_issue1813 (test.test_locale.TestMiscellaneous)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_locale.py", line 567, in test_getsetlocale_issue1813
locale.setlocale(locale.LC_CTYPE, loc)
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\locale.py", line 608, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
----------------------------------------------------------------------`test_subprocess`
Known Failing on: Linux
This fails in the following manner:
test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ... Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007fd77c231740 (most recent call first):
FAIL
======================================================================
FAIL: test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmp8hef0kr4/python/install/lib/python3.7/test/test_subprocess.py", line 436, in test_executable_without_cwd
executable=sys.executable)
File "/tmp/tmp8hef0kr4/python/install/lib/python3.7/test/test_subprocess.py", line 355, in _assert_cwd
self.assertEqual(47, p.returncode)
AssertionError: 47 != -6We're unsure what is going on here. The error from initfsencoding
is what happens when the first import during Py_Initialize()
fails. So it appears the test somehow can't locate the Python
standard library.
`test_tk`
Known Failing on: Linux
This fails in the following manner:
======================================================================
FAIL: test_from (tkinter.test.test_tkinter.test_widgets.ScaleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/test_tkinter/test_widgets.py", line 867, in test_from
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=float_round)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 106, in checkFloatParam
self.checkParam(widget, name, value, conv=conv, **kwargs)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 63, in checkParam
self.assertEqual2(widget[name], expected, eq=eq)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 47, in assertEqual2
self.assertEqual(actual, expected, msg)
AssertionError: 14.9 != 15.0This seems like a minor issue and might be a bug in the test itself.
`test_winconsoleio`
This fails as follows:
/* Detailed source-code truncated for AI context efficiency. */Test Skips
Linux
The following tests are skipped on Linux:
test_asdl_parser
: test irrelevant for an installed Python
test_clinic
: install/lib/Tools/clinic' path does not exist
test_dbm_gnu
: No module named '_gdbm'
test_devpoll
: test works only on Solaris OS family
test_gdb
: test_gdb only works on source builds at the moment.
test_kqueue
: test works only on BSD
test_msilib
: No module named 'msilib'
test_ossaudiodev
: [Errno 2] No such file or directory: '/dev/dsp'
test_startfile
: object <module 'os' from '.../install/lib/python3.7/os.py'> has no attribute 'startfile'
test_winconsoleio
: test only relevant on win32
test_winreg
: No module named 'winreg'
test_winsound
: No module named 'winsound'
test_zipfile64
: test requires loads of disk-space bytes and a long time to run
macOS
The following tests are skipped on macOS:
test_asdl_parser
: test irrelevant for an installed Python
test_clinic
: python/install/lib/Tools/clinic' path does not exist
test_dbm_gnu
: No module named '_gdbm'
test_devpoll
: test works only on Solaris OS family
test_epoll
: test works only on Linux 2.6
test_gdb
: Couldn't find gdb on the path
test_msilib
: No module named 'msilib'
test_multiprocessing_fork
: test may crash on macOS (bpo-33725)
test_nis
: No module named 'nis'
test_ossaudiodev
: No module named 'ossaudiodev'
test_spwd
: No module named 'spwd'
test_startfile
: object <module 'os' from '.../install/lib/python3.7/os.py'> has no attribute 'startfile'
test_tix
: tix is not built by this project
test_tk
: cannot run without OS X gui process
test_ttk_guionly
: cannot run without OS X gui process
test_winconsoleio
: test only relevant on win32
test_winreg
: No module named 'winreg'
test_winsound
: No module named 'winsound'
test_zipfile64
: test requires loads of disk-space bytes and a long time to run
Status (`docs/status.rst`)
.. _status:
============== Project Status
There is support for producing CPython distributions for Windows,
macOS, and Linux. All distributions are highly self-contained and have
limited shared library dependencies.
Target Notes
Linux x86_64 and aarch64 targets (x86_64-* and aarch64-*) are built on
native hardware using a modern LLVM toolchain.
All other architectures are cross-compiled on x86_64 using Debian-provided
cross-compilation tools. As a result, these targets are not as highly
optimized as aarch64 and x86_64 targets.
Test Failures
This repository contains a test-distribution.py script that can be
used to run the Python test harness from a distribution archive.
Currently, this script is only used to validate a limited set of
functionality for each distribution. The entire Python test harness is
not run on a regular basis. Work is ongoing to perform this type of
testing on a regular basis.
The details below on known failing and skipped tests are out of date. In
the future, this information will be updated and presented elsewhere.
Here, we track the various known failures when runningtest-distribution.py --stdlib -- /path/to/distribution.tar.zst -u all.
``test__locale``
Known failing on: Windows
This test fails as follows::
======================================================================
ERROR: test_float_parsing (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmpjx7a33kd\python\install\lib\test\test__locale.py", line 184, in test_float_parsing
if localeconv()['decimal_point'] != '.':
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
======================================================================
ERROR: test_lc_numeric_localeconv (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmpjx7a33kd\python\install\lib\test\test__locale.py", line 130, in test_lc_numeric_localeconv
formatting = localeconv()
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
----------------------------------------------------------------------``test_locale``
Known failing on: Windows
This test fails on Windows::
======================================================================
ERROR: test_getsetlocale_issue1813 (test.test_locale.TestMiscellaneous)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_locale.py", line 567, in test_getsetlocale_issue1813
locale.setlocale(locale.LC_CTYPE, loc)
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\locale.py", line 608, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
----------------------------------------------------------------------``test_subprocess``
Known Failing on: Linux
This fails in the following manner::
test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ... Could not find platform independent libraries
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to [:<exec_prefix>]
Fatal Python error: initfsencoding: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007fd77c231740 (most recent call first):
FAIL
======================================================================
FAIL: test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmp8hef0kr4/python/install/lib/python3.7/test/test_subprocess.py", line 436, in test_executable_without_cwd
executable=sys.executable)
File "/tmp/tmp8hef0kr4/python/install/lib/python3.7/test/test_subprocess.py", line 355, in _assert_cwd
self.assertEqual(47, p.returncode)
AssertionError: 47 != -6We're unsure what is going on here. The error from initfsencoding
is what happens when the first import during Py_Initialize()
fails. So it appears the test somehow can't locate the Python
standard library.
``test_tk``
Known Failing on: Linux
This fails in the following manner::
======================================================================
FAIL: test_from (tkinter.test.test_tkinter.test_widgets.ScaleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/test_tkinter/test_widgets.py", line 867, in test_from
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=float_round)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 106, in checkFloatParam
self.checkParam(widget, name, value, conv=conv, **kwargs)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 63, in checkParam
self.assertEqual2(widget[name], expected, eq=eq)
File "/tmp/tmpoqqjd5gi/python/install/lib/python3.7/tkinter/test/widget_tests.py", line 47, in assertEqual2
self.assertEqual(actual, expected, msg)
AssertionError: 14.9 != 15.0This seems like a minor issue and might be a bug in the test itself.
``test_winconsoleio``
This fails as follows::
======================================================================
ERROR: test_ctrl_z (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_winconsoleio.py", line 190, in test_ctrl_z
a, b = stdin.read(1), stdin.readall()
OSError: [WinError 87] The parameter is incorrect
======================================================================
ERROR: test_input (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_winconsoleio.py", line 144, in test_input
self.assertStdinRoundTrip('abc123')
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_winconsoleio.py", line 137, in assertStdinRoundTrip
actual = input()
OSError: [WinError 87] The parameter is incorrect
======================================================================
FAIL: test_partial_reads (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_winconsoleio.py", line 166, in test_partial_reads
self.assertEqual(actual, expected, 'stdin.read({})'.format(read_count))
AssertionError: b'\r\n' != b'\xcf\xbc\xd1\x9e\xd0\xa2\xce\xbb\xd0\xa4\xd0\x99\r\n' : stdin.read(1)
======================================================================
FAIL: test_partial_surrogate_reads (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test_winconsoleio.py", line 183, in test_partial_surrogate_reads
self.assertEqual(actual, expected, 'stdin.read({})'.format(read_count))
AssertionError: b'\xc3\x84\r\n' != b'\xf4\x81\xbf\xbf\xf4\x81\x80\x81\r\n' : stdin.read(1)
----------------------------------------------------------------------
Ran 10 tests in 0.006s
FAILED (failures=2, errors=2)
test test_winconsoleio failed
0:00:00 Re-running test__locale in verbose mode
test_float_parsing (test.test__locale._LocaleTests) ... ERROR
test_lc_numeric_basic (test.test__locale._LocaleTests) ... skipped 'nl_langinfo is not available'
test_lc_numeric_localeconv (test.test__locale._LocaleTests) ... ERROR
test_lc_numeric_nl_langinfo (test.test__locale._LocaleTests) ... skipped 'nl_langinfo is not available'
======================================================================
ERROR: test_float_parsing (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test__locale.py", line 184, in test_float_parsing
if localeconv()['decimal_point'] != '.':
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
======================================================================
ERROR: test_lc_numeric_localeconv (test.test__locale._LocaleTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\gps\AppData\Local\Temp\tmp8m94v2m5\python\install\lib\test\test__locale.py", line 130, in test_lc_numeric_localeconv
formatting = localeconv()
UnicodeDecodeError: 'locale' codec can't decode byte 0xa0 in position 0: decoding error
----------------------------------------------------------------------Test Skips
Linux
The following tests are skipped on Linux:
test_asdl_parser
test irrelevant for an installed Python
test_clinic
install/lib/Tools/clinic' path does not exist
test_dbm_gnu
No module named '_gdbm'
test_devpoll
test works only on Solaris OS family
test_gdb
test_gdb only works on source builds at the moment.
test_kqueue
test works only on BSD
test_msilib
No module named 'msilib'
test_ossaudiodev
[Errno 2] No such file or directory: '/dev/dsp'
test_startfile
object <module 'os' from '.../install/lib/python3.7/os.py'> has no attribute 'startfile'
test_winconsoleio
test only relevant on win32
test_winreg
No module named 'winreg'
test_winsound
No module named 'winsound'
test_zipfile64
test requires loads of disk-space bytes and a long time to run
macOS
The following tests are skipped on macOS:
test_asdl_parser
test irrelevant for an installed Python
test_clinic
python/install/lib/Tools/clinic' path does not exist
test_dbm_gnu
No module named '_gdbm'
test_devpoll
test works only on Solaris OS family
test_epoll
test works only on Linux 2.6
test_gdb
Couldn't find gdb on the path
test_msilib
No module named 'msilib'
test_multiprocessing_fork
test may crash on macOS (bpo-33725)
test_nis
No module named 'nis'
test_ossaudiodev
No module named 'ossaudiodev'
test_spwd
No module named 'spwd'
test_startfile
object <module 'os' from '.../install/lib/python3.7/os.py'> has no attribute 'startfile'
test_tix
tix is not built by this project
test_tk
cannot run without OS X gui process
test_ttk_guionly
cannot run without OS X gui process
test_winconsoleio
test only relevant on win32
test_winreg
No module named 'winreg'
test_winsound
No module named 'winsound'
test_zipfile64
test requires loads of disk-space bytes and a long time to run
Technotes (`docs/technotes.md`)
Technical Notes
How It Works
The first thing the build.py scripts do is bootstrap an environment
for building Python. Linux builds use Docker images based on deterministic
Debian snapshots selected for each target:
- x86-64 targets use Debian Jessie and a prebuilt Clang toolchain.
- aarch64 targets use Debian Stretch and a prebuilt Clang toolchain.
- Other cross-compiled targets generally use Debian Stretch and
Debian-provided GCC cross-compilers. - riscv64 targets use Debian Buster and a Debian-provided GCC
cross-compiler.
The selected toolchain is used to build Python's dependencies (OpenSSL,
ncurses, libedit, SQLite, etc.). Finally, Python itself is built.
Python is built in such a way that extensions are statically linked
against their dependencies. For example, instead of the sqlite3 Python
extension having a run-time dependency against libsqlite3.so, the
SQLite symbols are statically inlined into the Python extension object
file. Extension modules are statically linked into python rather than
provided as shared extensions in the lib-dynload directory.
_dbm and _tkinter are handled differently. On dynamically linked
Linux builds, _dbm is provided as a shared extension with Berkeley DB
statically linked. This allows the module to be easily removed when the
Berkeley DB license is undesired (see the DBM section below). On macOS,_dbm instead uses the system NDBM implementation. _tkinter is
also provided as a shared extension, with Tcl and Tk dynamically linked,
on builds that support shared extensions.
From the built Python, we produce an archive containing the raw Python
distribution (as if you had run make install) as well as other files
useful for downstream consumers.
Setup.local Hackery
Starting with Python 3.12, C extension modules are configured and built
using configure, Modules/Setup.stdlib, and Makefile. A
generated Modules/Setup.local file disables selected modules and
overrides whether others are linked statically or built as shared
libraries.
Prior to 3.12, many extensions were configured and built using setup.py
scripts. These scripts do not provide much flexibility and rely on default
behaviors in distutils, as well as other inline code in setup.py.
This default behavior is often undesirable for our desired outcome of
producing a standalone Python distribution.
Because of this, when building Python prior to 3.12, a custom Setup.local
file is generated that builds all C extensions in a specific manner.
The undesirable behavior of setup.py is bypassed and the Python C
extensions are compiled just the way we want.
Dependency Notes
DBM
Python has the option of building its _dbm extension against NDBM,
GDBM, and Berkeley DB. GDBM and its NDBM compatibility libraries are
licensed under GNU GPL Version 3. Modern versions of Berkeley DB are
licensed under GNU AGPL v3. Versions 6.0.19 and older are licensed under
the more permissive Sleepycat License.
On Linux, we build the _dbm extension against Berkeley DB 6.0.19. On
macOS, _dbm uses the NDBM implementation provided by the systemlibSystem library instead.
We explicitly disable the _gdbm extension on all targets to avoid
the GPL dependency.
readline / libedit / ncurses
Python has the option of building its readline extension against
either libreadline or libedit. libreadline is licensed under
GNU GPL Version 3, and libedit has a more permissive license.
libedit/libreadline link against a curses library, most likelyncurses. And ncurses has tie-ins with a terminal database. This
is a thorny situation, as terminal databases can be difficult to
distribute because end-users often want software to respect their
terminal databases. But for that to work, ncurses needs to be compiled
in a way that respects the user's environment.
On macOS, we use the system libedit and libncurses, which is
typically provided in /usr/lib.
On Linux, we build libedit and ncurses from source and statically
link against their respective libraries. Project releases before 2023 linked
against readline on Linux.
gettext / locale Module
The locale Python module exposes some functionality from the gettext
software (specifically libintl). (Technically, this functionality is exposed
from the _locale C extension module and locale re-exports symbols.)
gettext is GPL version 3 or later licensed. And having it statically linked
in the Python distribution via the _locale module can have licensing
implications.
Python's configure script probes for the ability to compile/link with-lintl. If it works, Python is linked against libintl. If it doesn't,libintl is omitted. (Search configure for ac_cv_lib_intl_textdomain
and -lintl references.)
With the container based build environment on Linux, presence of gettext
and libintl is deterministic. However, on macOS where there is no
sandboxing of the build environment, Python's configure script can find and
use a gettext/libintl installed outside the system default (e.g. via
Homebrew or MacPorts). This can result in the built Python referencing a shared
library not reliably present on every macOS machine. So our build system
disables the configure check.
This means that the gettext/libintl features in the Python distribution
are not available.
libnsl / nis Module
The nis Python extension module has a dependency on libnsl.
libnsl has historically been in base Linux distribution installations.
But it is being phased away, with it being an optional install in modern
versions of Fedora and RHEL.
Because the nis extension is perceived to be likely unused functionality,
we've decided to not build it instead of adding complexity to deal with
the libnsl dependency. See further discussion in
https://github.com/astral-sh/python-build-standalone/issues/51.
The nis module was deprecated in Python 3.11 and removed in 3.13.
Upgrading CPython
This section documents some of the work that needs to be performed
when upgrading CPython major versions.
Review Release Notes
CPython's release notes often have a section on build system changes.
e.g. https://docs.python.org/3/whatsnew/3.13.html#build-changes.
These are a must review.
`Modules/Setup`
The Modules/Setup file defines the default extension build settings.
We need to audit it for differences such as added/removed extensions,
changes to compile settings, etc just in case we have special code
handling an extension defined in this file.
See code in cpython.py dealing with this file.
Technotes (`docs/technotes.rst`)
.. _technotes:
=============== Technical Notes
How It Works
The first thing the build.py scripts do is bootstrap an environment
for building Python. Linux builds use Docker images based on deterministic
Debian snapshots selected for each target:
- x86-64 targets use Debian Jessie and a prebuilt Clang toolchain.
- aarch64 targets use Debian Stretch and a prebuilt Clang toolchain.
- Other cross-compiled targets generally use Debian Stretch and
Debian-provided GCC cross-compilers. - riscv64 targets use Debian Buster and a Debian-provided GCC
cross-compiler.
The selected toolchain is used to build Python's dependencies (OpenSSL,
ncurses, libedit, SQLite, etc.). Finally, Python itself is built.
Python is built in such a way that extensions are statically linked
against their dependencies. For example, instead of the sqlite3 Python
extension having a run-time dependency against libsqlite3.so, the
SQLite symbols are statically inlined into the Python extension object
file. Extension modules are statically linked into python rather than
provided as shared extensions in the lib-dynload directory.
_dbm and _tkinter are handled differently. On dynamically linked
Linux builds, _dbm is provided as a shared extension with Berkeley DB
statically linked. This allows the module to be easily removed when the
Berkeley DB license is undesired (see the DBM section below). On macOS,_dbm instead uses the system NDBM implementation. _tkinter is
also provided as a shared extension, with Tcl and Tk dynamically linked,
on builds that support shared extensions.
From the built Python, we produce an archive containing the raw Python
distribution (as if you had run make install) as well as other files
useful for downstream consumers.
Setup.local Hackery
Starting with Python 3.12, C extension modules are configured and built
using configure, Modules/Setup.stdlib, and Makefile. A
generated Modules/Setup.local file disables selected modules and
overrides whether others are linked statically or built as shared
libraries.
Prior to 3.12, many extensions were configured and built using setup.py
scripts. These scripts do not provide much flexibility and rely on default
behaviors in distutils, as well as other inline code in setup.py.
This default behavior is often undesirable for our desired outcome of
producing a standalone Python distribution.
Because of this, when building Python prior to 3.12, a custom Setup.local
file is generated that builds all C extensions in a specific manner.
The undesirable behavior of setup.py is bypassed and the Python C
extensions are compiled just the way we want.
Dependency Notes
DBM
Python has the option of building its _dbm extension against NDBM,
GDBM, and Berkeley DB. GDBM and its NDBM compatibility libraries are
licensed under GNU GPL Version 3. Modern versions of Berkeley DB are
licensed under GNU AGPL v3. Versions 6.0.19 and older are licensed under
the more permissive Sleepycat License.
On Linux, we build the _dbm extension against Berkeley DB 6.0.19. On
macOS, _dbm uses the NDBM implementation provided by the systemlibSystem library instead.
We explicitly disable the _gdbm extension on all targets to avoid
the GPL dependency.
readline / libedit / ncurses
Python has the option of building its readline extension against
either libreadline or libedit. libreadline is licensed under
GNU GPL Version 3, and libedit has a more permissive license.
libedit/libreadline link against a curses library, most likelyncurses. And ncurses has tie-ins with a terminal database. This
is a thorny situation, as terminal databases can be difficult to
distribute because end-users often want software to respect their
terminal databases. But for that to work, ncurses needs to be compiled
in a way that respects the user's environment.
On macOS, we use the system libedit and libncurses, which is
typically provided in /usr/lib.
On Linux, we build libedit and ncurses from source and statically
link against their respective libraries. Project releases before 2023 linked
against readline on Linux.
gettext / locale Module
The locale Python module exposes some functionality from the gettext
software (specifically libintl). (Technically, this functionality is exposed
from the _locale C extension module and locale re-exports symbols.)
gettext is GPL version 3 or later licensed. And having it statically linked
in the Python distribution via the _locale module can have licensing
implications.
Python's configure script probes for the ability to compile/link with-lintl. If it works, Python is linked against libintl. If it doesn't,libintl is omitted. (Search configure for ac_cv_lib_intl_textdomain
and -lintl references.)
With the container based build environment on Linux, presence of gettext
and libintl is deterministic. However, on macOS where there is no
sandboxing of the build environment, Python's configure script can find and
use a gettext/libintl installed outside the system default (e.g. via
Homebrew or MacPorts). This can result in the built Python referencing a shared
library not reliably present on every macOS machine. So our build system
disables the configure check.
This means that the gettext/libintl features in the Python distribution
are not available.
libnsl / nis Module
The nis Python extension module has a dependency on libnsl.
libnsl has historically been in base Linux distribution installations.
But it is being phased away, with it being an optional install in modern
versions of Fedora and RHEL.
Because the nis extension is perceived to be likely unused functionality,
we've decided to not build it instead of adding complexity to deal with
the libnsl dependency. See further discussion in
https://github.com/astral-sh/python-build-standalone/issues/51.
The nis module was deprecated in Python 3.11 and removed in 3.13.
Upgrading CPython
This section documents some of the work that needs to be performed
when upgrading CPython major versions.
Review Release Notes
CPython's release notes often have a section on build system changes.
e.g. https://docs.python.org/3/whatsnew/3.13.html#build-changes.
These are a must review.
``Modules/Setup``
The Modules/Setup file defines the default extension build settings.
We need to audit it for differences such as added/removed extensions,
changes to compile settings, etc just in case we have special code
handling an extension defined in this file.
See code in cpython.py dealing with this file.
--- METRICS ---
- Files Extracted: 14
- Estimated Token Budget: ~34587 tokens
- Canonical Reference: https://codewiki.google/github.com/astral-sh/python-build-standalone