Safeguard
Developer Tools•

How do you read a Python wheel filename and its compatibility tags?

A wheel filename encodes name, version, Python tag, ABI tag and platform tag. Learn to decode py3-none-any and cp312 style names and spot a wrong wheel.

Safeguard Security Team
4 min read

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

TagWhat it saysExamples
Python tagInterpreter implementation and versionpy3, cp312, pp310
ABI tagWhich Python binary interface compiled code needsnone, abi3, cp312
Platform tagOperating system and CPUany, 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 withMeaning
py3-none-any.whlPure Python, any Python 3, any platform
cp312-cp312-win32.whlCPython 3.12 build for 32 bit Windows
cp39-abi3-linux_x86_64.whlStable 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

  1. Does the filename normalization match your project name?
  2. Is a pure Python library tagged py3 and not cp?
  3. Do compiled wheels cover each platform you claim?
  4. 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

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.