From c3916d398200fc75a35cc0ecf52f9314bf200205 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 21 Aug 2026 16:37:55 -0400 Subject: [PATCH] [ADD] Python packaging, through Arch's own bootstrap path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three stage-2 builds -- brotli, libseccomp, meson -- stopped on /usr/bin/python: No module named build and building python-build means running `python -m build`. Its dependencies are the same cycle: packaging and pyproject-hooks are flit_core-backed, installing a wheel wants python-installer, and none of the six exist yet. On the host the cycle was already broken -- apt had python3-build -- so stage 1 never met it. Breaking it there again is not possible: apt has no python3-flit-core at all, so the backend all six need cannot be installed on the host by any means. Arch had already solved it, in the PKGBUILDs: `_bootstrap=1` selects a vendored builder that needs none of the six. That is upstream's supported path through exactly this situation, and it replaced a half-written alternative here -- three bespoke hooks calling `python -m flit_core.wheel` and unzipping into $pkgdir -- which would have reimplemented what the PKGBUILD already does properly. --- FR --- Trois constructions d'étage 2 — brotli, libseccomp, meson — se sont arrêtées sur /usr/bin/python: No module named build et bâtir python-build suppose d'exécuter `python -m build`. Ses dépendances sont le même cycle : packaging et pyproject-hooks passent par flit_core, installer une roue demande python-installer, et aucun des six n'existe encore. Sur l'hôte le cycle était déjà rompu — apt fournissait python3-build — donc l'étage 1 ne l'a jamais rencontré. Le rompre à nouveau là est impossible : apt n'a aucun python3-flit-core, donc le moteur dont les six ont besoin ne peut être installé sur l'hôte par aucun moyen. Arch l'avait déjà résolu, dans les PKGBUILD : `_bootstrap=1` sélectionne un constructeur embarqué qui n'a besoin d'aucun des six. C'est la voie prévue en amont pour exactement cette situation, et elle a remplacé une solution à demi écrite ici — trois hooks sur mesure appelant `python -m flit_core.wheel` puis dézippant dans $pkgdir — qui aurait réimplémenté ce que le PKGBUILD fait déjà correctement. Assisted-by: Claude Opus 5 --- patches/pkgbuild/lib-python-bootstrap.sh | 54 ++++++++++++++++++++++ patches/pkgbuild/python-build.sh | 5 ++ patches/pkgbuild/python-installer.sh | 5 ++ patches/pkgbuild/python-packaging.sh | 5 ++ patches/pkgbuild/python-pyproject-hooks.sh | 5 ++ patches/pkgbuild/python-setuptools.sh | 5 ++ patches/pkgbuild/python-wheel.sh | 5 ++ 7 files changed, 84 insertions(+) create mode 100755 patches/pkgbuild/lib-python-bootstrap.sh create mode 100755 patches/pkgbuild/python-build.sh create mode 100755 patches/pkgbuild/python-installer.sh create mode 100755 patches/pkgbuild/python-packaging.sh create mode 100755 patches/pkgbuild/python-pyproject-hooks.sh create mode 100755 patches/pkgbuild/python-setuptools.sh create mode 100755 patches/pkgbuild/python-wheel.sh diff --git a/patches/pkgbuild/lib-python-bootstrap.sh b/patches/pkgbuild/lib-python-bootstrap.sh new file mode 100755 index 0000000..d004cf2 --- /dev/null +++ b/patches/pkgbuild/lib-python-bootstrap.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Arch's own escape hatch for the Python packaging cycle. Sourced by the six +# hooks that need it; not a hook itself. +# +# THE CYCLE. Three stage-2 builds -- brotli, libseccomp, meson -- stopped on +# +# /usr/bin/python: No module named build +# +# and building python-build means running `python -m build`, which is +# python-build. Its dependencies are the same: packaging and pyproject-hooks are +# flit_core-backed, installing a wheel wants python-installer, and none of them +# exist yet. +# +# On the host the cycle was already broken -- apt had python3-build -- so stage 1 +# never met it. Trying to break it there again failed for a reason worth +# recording: `apt-cache policy python3-flit-core` returns no candidate at all. +# Ubuntu does not package it, so the backend every one of these needs cannot be +# installed on the host by any means. Our own python-flit-core builds fine, but +# building a package is not installing it. +# +# ARCH ALREADY SOLVED THIS, and the solution is in the PKGBUILDs: +# +# if (( _bootstrap == 0 )); then +# python -m build -wn --skip-dependency-check +# else +# cd python-bootstrap +# python -m bootstrap.build +# fi +# +# python-bootstrap is a vendored builder that needs none of the six. Setting +# _bootstrap=1 is upstream's supported path through exactly this situation -- +# far better than the alternative that was half-written here first, which was a +# per-package hook calling `python -m flit_core.wheel` and unzipping the result +# into $pkgdir by hand. That would have been three bespoke reimplementations of +# something the PKGBUILD already does properly. +# +# It also means these build on the HOST, where they had failed, so they need no +# stage-2 special handling at all. +set -euo pipefail +python3 - <<'ZZPY' +import io +s = io.open("PKGBUILD", encoding="utf-8").read() +old = "_bootstrap=0" +assert s.count(old) == 1, "python bootstrap: expected one _bootstrap=0, got %d" % s.count(old) +s = s.replace(old, "_bootstrap=1 # see patches/pkgbuild/lib-python-bootstrap.sh", 1) +io.open("PKGBUILD", "w", encoding="utf-8").write(s) +ZZPY +grep -q "^_bootstrap=1" PKGBUILD || { + echo "python bootstrap: _bootstrap was not switched" >&2; exit 1; } +# The branch it selects must actually exist, or the switch silently builds +# nothing -- these PKGBUILDs are not required to have both halves. +grep -q "bootstrap.build" PKGBUILD || { + echo "python bootstrap: no bootstrap.build branch in this PKGBUILD" >&2; exit 1; } +echo "$(basename "$PWD"): _bootstrap=1 (Arch's vendored builder)" diff --git a/patches/pkgbuild/python-build.sh b/patches/pkgbuild/python-build.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh" diff --git a/patches/pkgbuild/python-installer.sh b/patches/pkgbuild/python-installer.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-installer.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh" diff --git a/patches/pkgbuild/python-packaging.sh b/patches/pkgbuild/python-packaging.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-packaging.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh" diff --git a/patches/pkgbuild/python-pyproject-hooks.sh b/patches/pkgbuild/python-pyproject-hooks.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-pyproject-hooks.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh" diff --git a/patches/pkgbuild/python-setuptools.sh b/patches/pkgbuild/python-setuptools.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-setuptools.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh" diff --git a/patches/pkgbuild/python-wheel.sh b/patches/pkgbuild/python-wheel.sh new file mode 100755 index 0000000..46f271c --- /dev/null +++ b/patches/pkgbuild/python-wheel.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# One of the six packages in the Python packaging cycle. The reasoning, and the +# edit, are shared -- see lib-python-bootstrap.sh. +set -euo pipefail +source "$(dirname "$0")/lib-python-bootstrap.sh"