From 8f9254232296e1d3fa55fb14c1f104c90aa40fe9 Mon Sep 17 00:00:00 2001 From: William Barnhart Date: Thu, 16 Jul 2026 16:36:50 +0000 Subject: [PATCH 1/2] Pin black and isort to keep CI lint reproducible black and isort were unpinned in requirements/test.txt, so CI always installed the newest release. When isort 8.0.1 and black 26.5.1 shipped, their changed formatting output started failing 'Check linting' on otherwise-unchanged trees -- lint was passing or failing depending only on when the job happened to run. Pin both to the current versions (the ones the tree is already formatted for) so linting is reproducible. Bump them deliberately, together with a tree-wide reformat, in future. --- requirements/test.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index 8dfe2cdfa..8f17dcd81 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,5 +1,8 @@ -black -isort +# Formatters are pinned: new releases change formatting output and would +# fail `scripts/check` on an otherwise-unchanged tree (non-reproducible CI). +# Bump these deliberately together with a reformat. +black==26.5.1 +isort==8.0.1 autoflake flake8==5.0.4 # 5.0.4 can be upgraded to 6.0.0+ when we EOL Python 3.7 flake8-bugbear From b282d425ec57c89cae81b4a058bfdc07d13f8c71 Mon Sep 17 00:00:00 2001 From: William Barnhart Date: Fri, 17 Jul 2026 01:04:47 +0000 Subject: [PATCH 2/2] Guard formatter pins with a Python 3.10+ marker black 26.5.1 and isort 8.0.1 require Python >= 3.10, so pinning them unconditionally broke 'pip install -r requirements/test.txt' on the Python 3.9 test-matrix jobs. black/isort are lint-only and only run in the lint job (PYTHON_LATEST), so pin them on 3.10+ and fall back to an unpinned install on 3.9, where they are installed but never invoked. --- requirements/test.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index 8f17dcd81..832762190 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,8 +1,13 @@ -# Formatters are pinned: new releases change formatting output and would -# fail `scripts/check` on an otherwise-unchanged tree (non-reproducible CI). -# Bump these deliberately together with a reformat. -black==26.5.1 -isort==8.0.1 +# Formatters are pinned so `scripts/check` is reproducible: new releases +# change formatting output and would fail lint on an otherwise-unchanged +# tree. They are lint-only tools, run only by the lint job (PYTHON_LATEST). +# The current pins require Python >= 3.10, so guard them with a marker and +# fall back to an unpinned install on 3.9 (installed there but never run). +# Bump the pins deliberately, together with a tree-wide reformat. +black==26.5.1; python_version >= "3.10" +black; python_version < "3.10" +isort==8.0.1; python_version >= "3.10" +isort; python_version < "3.10" autoflake flake8==5.0.4 # 5.0.4 can be upgraded to 6.0.0+ when we EOL Python 3.7 flake8-bugbear