Deferred from #99, which is closed. Not a bug today — filing so it isn't rediscovered the hard way later.
Current state
Repair Wheel in gitlab-ci.yml.jinja invokes an interpreter by absolute path with a hardcoded ABI:
script:
- /opt/python/cp313-cp313/bin/pip install --upgrade "xmsconan>=…" -i …
- /opt/python/cp313-cp313/bin/xmsconan_wheel_repair --wheel-dir wheelhouse
The job runs in one of three images depending on [ci].docker_image / [ci].xvfb: an explicit override, conan-gcc13-x11-gdal-py<version>, or quay.io/pypa/manylinux_2_28_x86_64.
Why this is fine right now
The Aquaveo conan images are manylinux-derived and ship every ABI, not only the one their tag names — the tag just sets which interpreter is default on PATH. Verified by running them:
$ docker run --rm ghcr.io/aquaveo/conan-gcc13-x11-gdal-py3.14 ls /opt/python
cp310-cp310 cp311-cp311 cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t
cp315-cp315 cp315-cp315t cp39-cp39 pp311-pypy311_pp73
$ docker run --rm ghcr.io/aquaveo/conan-gcc13-x11-gdal-py3.14 python --version
Python 3.14.7
Same for the py3.13 variant, and manylinux_2_28_x86_64 carries cp314-cp314 as well. So cp313-cp313 resolves in every image this job can run in, on every branch, regardless of what [ci].linux_python_versions says.
It also doesn't matter which interpreter is used: xmsconan_wheel_repair only hosts auditwheel, which keys off each wheel's own tags.
Why it will stop being fine
manylinux removes Pythons as they reach EOL. cp39-cp39 is still in the image above and will not be forever; cp313 follows the same path in time. When the base image drops it, Repair Wheel breaks for every project at once, on a job nobody touched, for a reason unconnected to the change that happens to be in flight. That is an expensive failure to debug cold.
Suggested fix
Derive the path from the version that already selects the image, so it is correct by construction — the image is named py<V>, so cp<V> is guaranteed present.
An implementation with tests exists on the branch fix/xvfb-repair-wheel-interpreter (commit 02ba259, CI green): a _cp_tag() helper feeding a gitlab_linux_cp_tag template value, plus tests that the interpreter matches its image with xvfb on/off under a fanned-out Linux list, and that a single-version project still renders cp313-cp313 byte-identically. Branch left in place; either resurrect or rewrite it.
One wording note if it is resurrected: that branch's docs/USAGE.md edits imply the path must track the image, which overstates it. It tracks the image by construction, which is the actual argument.
Trigger to act
Whichever comes first:
manylinux_2_28 drops cp313-cp313, or announces it
- Python 3.13 reaches EOL
- Any image used by this job stops shipping the full ABI set
Background
Originally raised as a code-quality point in review on #96. I first dismissed it on the incorrect grounds that the x11-gdal image has no /opt/python tree, then opened #99 on the equally incorrect grounds that the tree is per-ABI and #96 had introduced a live break. Both claims came from reading image metadata and PATH rather than running ls. The finding was always a fair robustness observation; it was never a bug.
Deferred from #99, which is closed. Not a bug today — filing so it isn't rediscovered the hard way later.
Current state
Repair Wheelingitlab-ci.yml.jinjainvokes an interpreter by absolute path with a hardcoded ABI:The job runs in one of three images depending on
[ci].docker_image/[ci].xvfb: an explicit override,conan-gcc13-x11-gdal-py<version>, orquay.io/pypa/manylinux_2_28_x86_64.Why this is fine right now
The Aquaveo conan images are manylinux-derived and ship every ABI, not only the one their tag names — the tag just sets which interpreter is default on
PATH. Verified by running them:Same for the py3.13 variant, and
manylinux_2_28_x86_64carriescp314-cp314as well. Socp313-cp313resolves in every image this job can run in, on every branch, regardless of what[ci].linux_python_versionssays.It also doesn't matter which interpreter is used:
xmsconan_wheel_repaironly hostsauditwheel, which keys off each wheel's own tags.Why it will stop being fine
manylinux removes Pythons as they reach EOL.
cp39-cp39is still in the image above and will not be forever;cp313follows the same path in time. When the base image drops it,Repair Wheelbreaks for every project at once, on a job nobody touched, for a reason unconnected to the change that happens to be in flight. That is an expensive failure to debug cold.Suggested fix
Derive the path from the version that already selects the image, so it is correct by construction — the image is named
py<V>, socp<V>is guaranteed present.An implementation with tests exists on the branch
fix/xvfb-repair-wheel-interpreter(commit02ba259, CI green): a_cp_tag()helper feeding agitlab_linux_cp_tagtemplate value, plus tests that the interpreter matches its image withxvfbon/off under a fanned-out Linux list, and that a single-version project still renderscp313-cp313byte-identically. Branch left in place; either resurrect or rewrite it.One wording note if it is resurrected: that branch's
docs/USAGE.mdedits imply the path must track the image, which overstates it. It tracks the image by construction, which is the actual argument.Trigger to act
Whichever comes first:
manylinux_2_28dropscp313-cp313, or announces itBackground
Originally raised as a code-quality point in review on #96. I first dismissed it on the incorrect grounds that the x11-gdal image has no
/opt/pythontree, then opened #99 on the equally incorrect grounds that the tree is per-ABI and #96 had introduced a live break. Both claims came from reading image metadata andPATHrather than runningls. The finding was always a fair robustness observation; it was never a bug.