Pure Python Wheels vs Binary Wheels Explained
Python wheels are the standard built-package format used to
distribute libraries via tools like pip. The primary
distinction between a pure Python wheel (denoted by tags like
py3-none-any) and an architecture-specific binary wheel
lies in the presence of compiled machine code. Pure Python wheels
contain only platform-agnostic Python scripts, allowing a single build
to run across any operating system and CPU architecture. Conversely,
binary wheels contain pre-compiled code—such as C, C++, or Rust
extensions—meaning they are strictly bound to a specific operating
system, Python runtime ABI, and processor architecture.
Filename Tag Structure
The difference between these two wheel types is immediately apparent
in their wheel filename tags, which follow the
distribution-version-python_tag-abi_tag-platform_tag.whl
convention:
- Pure Python Wheel (
py3-none-any):py3: Works on Python 3 (orpy2.py3for universal Python 2/3 compatibility).none: Has no Application Binary Interface (ABI) requirement.any: Runs on any platform or architecture (macOS, Windows, Linux, ARM, x86_64).
- Architecture-Specific Binary Wheel (e.g.,
cp311-cp311-manylinux_2_17_x86_64):cp311: Targets CPython version 3.11 specifically.cp311: Requires the matching CPython 3.11 C-API/ABI.manylinux_2_17_x86_64: Runs strictly on 64-bit x86 Linux distributions meeting themanylinux_2_17standard.
Contents and Execution
A pure Python wheel unpacks into regular .py source
files and package metadata. When executed, the host environment’s Python
interpreter simply compiles these files into bytecode
(.pyc) on demand. Because there are no native extensions,
execution relies entirely on the Python virtual machine.
An architecture-specific binary wheel includes compiled shared libraries alongside any Python code:
.sofiles on Linux.pydfiles on Windows.dylibor.sofiles on macOS
These compiled extensions interact directly with the CPython C-API. Because they consist of native machine instructions, they run directly on the host processor without interpretation, typically offering higher computational performance for tasks like numerical computing, cryptography, and image processing.
Portability and Maintenance
Maintaining a pure Python package is straightforward: a maintainer
builds the wheel once (python -m build --wheel) and uploads
that single .whl file to the Python Package Index (PyPI).
That lone artifact serves users across all operating systems and Python
3 minor versions.
Binary wheels demand a complex build and release pipeline. Maintainers must compile individual wheels for every supported combination of:
- Operating System: Windows, macOS, Linux.
- CPU Architecture: x86_64, aarch64/ARM64, etc.
- Python Minor Version: Python 3.9, 3.10, 3.11, 3.12, each having distinct ABIs.
If a user requests a binary package on an unsupported platform (such
as a newly released Python version or a less common CPU architecture),
pip cannot use existing binary wheels. It must fall back to
downloading the source distribution (.tar.gz) and compiling
the native code locally, which requires development headers, compilers,
and external libraries on the user's machine.