Skip to content

fix: floor PyYAML per interpreter and gate every matrix entry - #135

Merged
lesnik512 merged 1 commit into
mainfrom
ci/floors-matrix
Sep 23, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
ci/floors-matrix

Conversation

@lesnik512

@lesnik512 lesnik512 commented Sep 23, 2026

Copy link
Copy Markdown
Member

floors ran on 3.10 and 3.14 only, against a six-entry pytest matrix. The job comment
justifies dropping 3.14t (no PyYAML release ships a cp314t wheel, which
the standard explicitly
permits and cites this repo for). It says nothing about 3.11, 3.12 and 3.13, which were
simply absent. §7: "Every matrix entry: wheel coverage is per interpreter, so two interpreters
that resolve the same versions can still disagree on whether those versions install."

Adding the three entries showed the declared floor was wrong on two of them.

The floor was not reachable at 3.12 or 3.13

PyYAML's cp3* wheel coverage:

release adds
6.0 cp310, cp311
6.0.1 cp312
6.0.2 cp313
6.0.3 cp314

So PyYAML>=6 claimed a floor that no wheel satisfies on 3.12 or 3.13:

$ uv venv --python 3.12 && uv pip install --only-binary PyYAML 'PyYAML==6.0'
hint: Wheels are required for `pyyaml` because building from source is disabled for `pyyaml`

3.13 gives the same; 3.11 installs. §7 is explicit that this is not a floor: "a floor reachable
only by compiling an sdist is not a floor a user installing a wheel can reach."

Why the existing job did not catch it

Not because of the matrix alone. Wheel-only does not verify the declared floor, it verifies the
declared range. A version with no wheel becomes ineligible, and --resolution lowest-direct then
picks the lowest version that does have one. So even with 3.12 in the matrix the old job would
have gone green: it resolves 6.0.1, reports success, and never touches the 6.0 the package
declares.

Both spellings §7 offers behave identically here (uv 0.12.5, 3.12, --resolution lowest-direct):

flag specifier result
--no-build PyYAML>=6 ok, resolves 6.0.1
--only-binary PyYAML PyYAML>=6 ok, resolves 6.0.1
--no-build PyYAML==6.0 fails, no wheel
--only-binary PyYAML PyYAML==6.0 fails, no wheel
none PyYAML>=6 fails, sdist build error

The last row is the irony: without the wheel-only flag, uv picks 6.0 and dies compiling it on
3.12. The flag is what let the range slide up and pass.

So the fix has to be the declaration, not the job. Splitting the floor per interpreter makes the
resolved version equal the declared one on every leg, which is what turns a green leg into evidence
about the floor rather than about the range. §7 currently says floors "is the only job that tests"
the declared floor; strictly it tests the range unless the declaration is pinned this tightly. That
belongs in a standard PR, not this one.

Verified

Each leg from a clean .venv, uv pip install --resolution lowest-direct --only-binary PyYAML ".[yaml]" then the import smoke, resolving exactly the declared floor for its interpreter:

3.10  ok  pyyaml=6.0
3.11  ok  pyyaml=6.0
3.12  ok  pyyaml=6.0.1
3.13  ok  pyyaml=6.0.2
3.14  ok  pyyaml=6.0.3

just lint-ci clean; just test-ci 1471 passed, 100% coverage. Local runs are macOS arm64, so CI
is the verdict on manylinux coverage.

@lesnik512
lesnik512 merged commit d52e93f into main Sep 23, 2026
15 checks passed
@lesnik512
lesnik512 deleted the ci/floors-matrix branch September 23, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant