In the wheel filename app-2.1-cp314-cp314-manylinux_2_28_x86_64.whl, what do the last three fields mean?
answer
- Read the filename right to left
- Three fields after the version
- Interpreter, then ABI, then platform
- cp314 is CPython 3.14
- none plus any means pure Python
basics
~20 sThey are the wheel's compatibility tags: cp314 is the interpreter tag (CPython 3.14), the second cp314 is the ABI it was compiled against, and manylinux_2_28_x86_64 is the platform. An installer takes the wheel only when all three match.
solid answer
~50 sA wheel filename is structured data, not a label. Its grammar is `{distribution}-{version}(-{build})?-{python tag}-{abi tag}-{platform tag}.whl`, so the three hyphen-separated fields before `.whl` are the compatibility tags. `cp314` is the **interpreter tag**: this code targets CPython 3.14 (`py3` would mean any Python 3, `pp311` a PyPy release). The second `cp314` is the **ABI tag**: it was compiled against that interpreter's binary interface; `none` means it contains no compiled code, while `abi3` means the limited API and is installable on standard CPython from its floor version upward. `manylinux_2_28_x86_64` is the **platform tag**: a Linux x86-64 host whose glibc is at least 2.28. At install time pip computes the ordered set of tags the running interpreter supports and takes the first candidate whose tags are in that set; if none is, it falls back to the source distribution and builds.
code
python · 3 linesname = "app-2.1-cp314-cp314-manylinux_2_28_x86_64.whl"
distribution, version, python_tag, abi_tag, platform_tag = name[:-4].split("-")
print(python_tag, abi_tag, platform_tag, sep="\n")go deeper
Recall that the letters after the version are not decoration: they say which Python and which machine the file is for. Be able to spot a pure-Python wheel from py3-none-any at a glance.
Explain all three fields cleanly and name a real value for each, including what none and any mean. An interviewer expects you to derive from a filename whether the file could possibly install on the machine in front of you.
Show that you use filenames diagnostically: reading a project's published files to predict whether a deploy target will get a binary or a compile, and spotting a missing interpreter or architecture before it becomes a broken pipeline.
Own the policy: which interpreter versions, architectures and libc baselines your organisation promises binaries for, what that build matrix costs, and when a stable-ABI artefact replaces a per-version one.
## The filename is the metadata A wheel is a zip archive with a fixed naming convention, and that name is the whole compatibility contract. An installer never opens the archive to decide whether it fits your machine; it parses the filename. The grammar is: ``` {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl ``` So `app-2.1-cp314-cp314-manylinux_2_28_x86_64.whl` is distribution `app`, version `2.1`, no build tag, and then the three compatibility fields. The optional build tag is a disambiguator (it must start with a digit) used when the same version is rebuilt; it is rare in published artefacts. ## The interpreter tag The first of the three says which Python implementation and version the code was written or compiled for. `cp314` means CPython 3.14. `cp39` means CPython 3.9. `pp311` means a PyPy targeting Python 3.11. `py3` means any Python 3 implementation, and `py2.py3` — a dot-separated *set* — means either major version. Pure-Python projects publish `py3`; anything with compiled code publishes a separate wheel per interpreter version, because the C API differs between minor releases. ## The ABI tag The second field is the binary interface the compiled objects inside were linked against. Common values: - `none` — there is no compiled code at all, so no ABI constraint. Pairs with `py3` and a platform tag of `any`. - `cp314` — compiled against CPython 3.14's full C API. It will not load on 3.13 or 3.15. - `abi3` — compiled against the limited API, whose symbols are stable across releases; combined with an interpreter tag such as `cp39`, it means "CPython 3.9 and later" on standard builds, so one artefact spans many releases. - `cp314t` — the free-threaded CPython 3.14 build, whose ABI differs from the standard one; the trailing `t` marks it. Historically this field also carried flags such as `m` (pymalloc) and `u` (wide unicode); those are gone in modern releases, which is why current ABI tags look like a bare `cp3XX`. ## The platform tag The third field describes the operating system, C library baseline and CPU. `any` means no constraint. Real ones include `manylinux_2_28_x86_64` (Linux, glibc 2.28 or newer, x86-64), `musllinux_1_2_aarch64` (musl-based Linux on ARM64), `macosx_11_0_arm64` and `win_amd64`. A wheel that names glibc will never install on a musl-based image and vice versa, and an ARM64 wheel will never install on an x86-64 host. ## Compressed tag sets Any of the three fields may hold several values separated by dots, and the filename then means the cross product. `py2.py3-none-any` is the classic universal wheel. Compiled Linux wheels are often published as `manylinux_2_17_x86_64.manylinux2014_x86_64`, which is the same baseline written twice — once in the modern perennial spelling, once in the legacy alias — so that older installers that do not understand the newer form still recognise it. ## How the match actually happens The interpreter builds a *priority-ordered* list of the tag triples it accepts: its exact interpreter and ABI first, then more general fallbacks, ending with `py3-none-any`. The installer walks the available files and takes the first one whose tag triple appears in that list — which is why a platform-specific wheel wins over a pure-Python one for the same version. You can inspect that list with `python -m pip debug --verbose`, and you can see the pieces the interpreter contributes with `sysconfig`. ## What the name does not tell you The tags answer "can this file be installed here", and nothing else. They do not encode the project's dependencies, its supported Python floor as declared in metadata, the compiler or build backend used, or whether the code is *correct* on your platform. A wheel whose tags match can still refuse to import if a shared library it expected to find on the system is missing, and a project can publish a matching wheel while its metadata declares a Python requirement your interpreter fails. Tags are a necessary condition for an install, not a sufficient one for a working import. ## Why it matters in practice Every "pip suddenly started compiling", "this wheel is not supported on this platform" and "the container image works on my laptop but not in CI" traces back to one of these three fields. Reading a wheel filename tells you, before you install anything, whether a project ships binaries for your interpreter at all, whether it pinned itself to one Python minor version, and whether its Linux baseline is newer than the base image you deploy on. Being able to decode it on sight is the difference between guessing at an install failure and naming its cause in one line.
- What does a wheel named tool-3.2-py3-none-any.whl tell you about its contents?That it is pure Python: `py3` means any Python 3 implementation, `none` means nothing inside was compiled against an interpreter ABI, and `any` means no operating-system or CPU constraint. One such file serves every platform, and installing it is a copy rather than a build. It is also a hint that the project has no C extension, so it cannot be the source of a compiler error during install.
- Why do published Linux wheels often carry two dotted platform tags, such as manylinux_2_17_x86_64.manylinux2014_x86_64?Because a tag field may hold a dot-separated set, and those two spellings name the same glibc 2.17 baseline. The perennial form is what modern installers prefer; the legacy alias is kept so that older installers, which only know the fixed alias names, still recognise the file. It is one artefact advertising itself under both vocabularies, not two different baselines.
- If both a py3-none-any wheel and a cp314-cp314-manylinux wheel exist for one version, which does pip install?The platform-specific one. The interpreter produces its supported tags in priority order, most specific first, and the installer takes the first candidate whose tags appear in that list. The pure-Python wheel sits at the bottom of that order as a fallback, so a project shipping both gets its compiled build used wherever the tags fit and the portable build everywhere else.
The three tags are the shoe size, the width and the fitting on a box: the installer reads the box rather than trying the shoe on.
saying these in an interview costs you the question
- Thinks .whl files are interchangeable across platforms
- Reads manylinux as any Linux, any version
- Confuses the interpreter tag with the ABI tag
- Believes the platform tag names a distribution such as Ubuntu
- Assumes pip rewrites or recompiles a wheel to fit
- Thinks the tags are advisory rather than a hard match