The build number is like the release number in RPM. It is necessary because the person who does the build might not be the same person who released the versioned software, and they need to be able to correct a mistake. It should sort after the tags.
Installers decide on the version number separate from any wheel logic. Then the installer gets a list of all available wheels (and the source) for that version of the software.
Suppose a Python interpreter supports these wheel tags. The list of tags can be considered as a distance between or similarity to a wheel with that tag and the install target. We want the wheel that is the closest to the current interpreter. The first tag means “complied on this machine”. Later / farther tags mean “compatible, but not compiled for/on this specific interpreter+machine”. Wheels with tags not in the list are thrown out as incompatible.
[(0, 'py37-none-linux_x86_64'),
(1, 'py3-none-linux_x86_64'),
(2, 'py36-none-linux_x86_64'),
(3, 'py35-none-linux_x86_64'),
(4, 'py34-none-linux_x86_64'),
(5, 'py33-none-linux_x86_64'),
(6, 'py32-none-linux_x86_64'),
(7, 'py31-none-linux_x86_64'),
(8, 'py30-none-linux_x86_64'),
(9, 'py37-none-any'),
(10, 'py3-none-any'),
(11, 'py36-none-any'),
(12, 'py35-none-any'),
(13, 'py34-none-any'),
(14, 'py33-none-any'),
(15, 'py32-none-any'),
(16, 'py31-none-any'),
(17, 'py30-none-any')]
90% of the time it is easy because there is only one compatible wheel.
Suppose we are installing beaglevote-1.0
that can be compiled without its extension modules. The installer finds
beaglevote-1.0-py37-none-linux_x86_64.whl
beaglevote-1.0-1-py37-none-linux_x86_64.whl
beaglevote-1.0-1a-py37-none-linux_x86_64.whl
beaglevote-1.0-py37-none-macosx_10_6_x86_64.whl
beaglevote-1.0-py3-none-any.whl
It throws out the macos wheel. The remaining wheels are ranked as follows
(0, (1, "a")) beaglevote-1.0-1a-py37-none-linux_x86_64.whl
(0, (1, "")) beaglevote-1.0-1-py37-none-linux_x86_64.whl
(0, (-1, "")) beaglevote-1.0-py37-none-linux_x86_64.whl
(10, (-1, "")) beaglevote-1.0-py3-none-any.whl
Sort by the smallest tag rank and the largest numeric and alphanumeric parts of the build tag. If not given an implicit build number (-1, "")
sorts before any explicit build tag.
We have also discovered that you can have identically named wheels in your search path. Installers tend to prefer wheels earlier in the search path, e.g. an already downloaded wheel takes preference over one off pypi.