From 455a61a9690a8234090b86cc67d522fade32ba88 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Thu, 27 Aug 2026 11:19:40 -0500 Subject: [PATCH] Pin the CI interpreter and its ABI in the update-env step conda-forge ships two ABIs for CPython 3.13+, and the "Update env" step did not restate ``python``, so the solver was free to replace the interpreter setup-miniconda installed. Three of the last sixteen python 3.14 draws on ubuntu-24.04-arm did exactly that: the log reads ``python 3.14.7-h6bfacdd_100_cp314 --> 3.14.7-hefd156b_0_cp314t`` and pytest then reports "Python: 3.14.7 free-threading build". Two of the three passed only because they also drew pandas 3.0. The third drew pandas 2.3, whose extension raises "The global interpreter lock (GIL) has been enabled to load module 'pandas._libs.pandas_parser'", and ``filterwarnings = error`` turns that into a collection error. It took test_formatting.py and test_recorder.py down with it, the second only because the first had left pandas half-imported. The window opened on 2026-08-19, when conda-forge uploaded python 3.14.7 for linux-aarch64 in both ABIs. Re-solving the failing job's own spec set per platform: linux-aarch64 and osx-arm64 both pick ``cp314t`` today, so macos-latest is on the same fuse and has simply not drawn 3.14 with an unlucky pandas yet. linux-64, osx-64 and win-64 pick the GIL build either way, which is why this has been an arm-only symptom. ``python-gil`` pins ``python_abi``; restating ``python=`` pins the version, since ``python-gil`` alone constrains only the ABI and its own version is left open. setup-miniconda's ``python-version`` is equally ABI-free, so this step is where both get settled. Re-solved with the pair added: every platform lands on a ``cp314`` build, and no draw becomes unsatisfiable or downgrades numpy, numba, pandas or psg, including python 3.11 with numpy 1.24 and scipy 1.9. python-gil has builds for 3.9 through 3.14, so one spec covers every version in the pool. The pypy guard matches the neighbouring lines: ``pypy python-gil`` is unsatisfiable, so an unguarded spec would hard-fail a pypy draw if one is ever added back. python-suitesparse-graphblas pins the same pair in ``.github/workflows/test.yml``, and asks for ``python-freethreading`` on the matrix entries that want the other ABI. An entry like that would be worth having here too, but it is a coverage decision rather than a fix, so it is not in this commit. --- .github/workflows/test_and_build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/test_and_build.yml b/.github/workflows/test_and_build.yml index 69fab3770..4fa881504 100644 --- a/.github/workflows/test_and_build.yml +++ b/.github/workflows/test_and_build.yml @@ -195,6 +195,17 @@ jobs: echo "versions: np${npver} sp${spver} pd${pdver} ak${akver} nx${nxver} numba${numbaver} yaml${yamlver} sparse${sparsever} psg${psgver}" set -x # echo on + # conda-forge ships two ABIs for CPython 3.13+, and this step did not + # restate ``python``, so the solver was free to replace the interpreter + # setup-miniconda installed: a 3.14 draw on ubuntu-24.04-arm became + # 3.14.7-*_cp314t, where pandas 2.3 raises a GIL RuntimeWarning that + # filterwarnings=error turns into a collection error. Restating the + # version pins the interpreter and ``python-gil`` pins python_abi to + # the GIL build; setup-miniconda's own ``python-version`` above is + # equally ABI-free, so this covers that step too. + # python-suitesparse-graphblas pins the same pair in + # .github/workflows/test.yml, and asks for python-freethreading on the + # matrix entries that want the other ABI. $(command -v mamba || command -v conda) install -c nodefaults \ packaging pip pytest coverage pytest-randomly cffi donfig tomli c-compiler make \ pyyaml${yamlver} ${sparse} pandas${pdver} scipy${spver} numpy${npver} ${awkward} \ @@ -204,6 +215,7 @@ jobs: ${{ steps.sourcetype.outputs.selected == 'upstream' && 'cython' || '' }} \ ${{ steps.sourcetype.outputs.selected != 'wheel' && '"graphblas>=7.4"' || '' }} \ ${{ contains(steps.pyver.outputs.selected, 'pypy') && 'pypy' || '' }} \ + ${{ !contains(steps.pyver.outputs.selected, 'pypy') && format('python={0} python-gil', steps.pyver.outputs.selected) || '' }} \ ${{ matrix.os == 'windows-latest' && 'cmake' || 'm4' }} \ # ${{ matrix.os != 'windows-latest' && 'pytest-forked' || '' }} # to investigate crashes - name: Build extension module