A wheel filename has five parts in order: distribution name, version, Python tag, ABI tag and platform tag, with an optional build tag. For example, py3-none-any means any Python 3, no ABI requirement, any platform. Installers use those last three tags to choose a compatible wheel.
The pattern
The binary distribution specification gives the pattern in a fixed order.
distribution-version(-build tag)-python tag-abi tag-platform tag.whl
Each part is separated by a hyphen, so none of the parts can contain one. That is why names have hyphens or dots replaced with underscores inside wheel filenames.
Reading the three tags
| Tag | What it says | Examples |
|---|---|---|
| Python tag | Interpreter implementation and version | py3, cp312, pp310 |
| ABI tag | Which Python binary interface compiled code needs | none, abi3, cp312 |
| Platform tag | Operating system and CPU | any, win32, linux_x86_64 |
In the Python tag, py means generic Python and cp means CPython. The spec stresses that py3 is not shorthand for py30. It means the packager intentionally released a wheel that works across Python 3.
The ABI tag abi3 refers to CPython's stable ABI, so one compiled wheel can serve several Python versions. none means the wheel contains no compiled extension that depends on an ABI.
Examples decoded
| Filename ends with | Meaning |
|---|---|
| py3-none-any.whl | Pure Python, any Python 3, any platform |
| cp312-cp312-win32.whl | CPython 3.12 build for 32 bit Windows |
| cp39-abi3-linux_x86_64.whl | Stable ABI build for CPython 3.9 and later on Linux x86_64 |
Treat the third row as an illustration of the format. Linux wheels meant for public distribution normally use manylinux tags rather than the plain linux tag, as covered in what manylinux means.
What the build tag is
The optional build tag is a number that breaks ties when two wheels match in every other way. The specification warns that build numbers are not part of the version and are hard to reference outside the Python ecosystem, for example when fixing a vulnerability. If you need to ship a rebuilt artifact that others must be able to refer to, create a new version instead.
Why you should care when installing
If your library publishes only a py3-none-any wheel, every user gets the same file. If it publishes platform specific wheels, a user on an unusual platform may get no match and fall back to the sdist, which means a local build. The packaging guide describes this fallback explicitly.
A quick sanity check for maintainers
- Does the filename normalization match your project name?
- Is a pure Python library tagged py3 and not cp?
- Do compiled wheels cover each platform you claim?
- Does the version in the name match the version in METADATA?
Safeguard's SBOM and dependency scanning record package names and versions. A free scan shows how a project's dependencies resolve.
Quick check
What does any mean in a wheel filename?
It is the platform tag for wheels that work on every platform. It usually pairs with none and a py tag for pure Python code.
Why is my wheel named with underscores?
Hyphens separate the filename parts, so runs of hyphens, dots and underscores in the project name become a single underscore.
Can two wheels have the same version?
Yes, if their tags differ. A pure Python wheel and several platform wheels can all share one version.
Sources
- Binary distribution format, Python Packaging User Guide
- Platform compatibility tags, Python Packaging User Guide
- The Packaging Flow, Python Packaging User Guide
Last reviewed: 19 October 2026.