From fcc6de4ee77eb3e7ee9abf7785e7369ce17b4179 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 20 Sep 2026 17:19:49 +0300 Subject: [PATCH] ci: resolve the floors wheel-only; fix the 3.13 pydantic floor `uv sync --resolution lowest-direct` builds a missing wheel from source, so the `lowest` leg went green on a floor that still fails anywhere without a build toolchain. `--no-build` makes that a resolution error instead. It immediately found one: `pydantic>=2.8` on 3.13 is a wheel-coverage floor that does not cover the wheel. 2.8.0 carries pydantic-core 2.20.0, which ships no cp313 wheel; 2.8.1 carries 2.20.1, which does. The matrix gains 3.12. Its floors resolve to the same versions as 3.11, which is why it was left out, but wheel coverage is per-interpreter and version equality does not imply it. --- .github/workflows/_checks.yml | 11 ++++++++--- pyproject.toml | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/_checks.yml b/.github/workflows/_checks.yml index 2a98dda..0f7b3c1 100644 --- a/.github/workflows/_checks.yml +++ b/.github/workflows/_checks.yml @@ -88,14 +88,16 @@ jobs: # The declared floors are part of what we ship, and nothing else in CI installs # them: `pytest` and `scheduled-dep-check` both resolve highest. That is how # 0.13.2 shipped `faststream>=0.7.1` and stayed green until 0.7.6 broke a user. - # This leg resolves the lower bound instead. One interpreter per distinct floor - # set: 3.11 for the unmarked floors, 3.13 and 3.14 for the marked ones. + # This leg resolves the lower bound instead, on every supported interpreter: + # a floor's wheel coverage is per-interpreter, so two interpreters resolving + # the same versions can still disagree on whether those versions install. runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: - "3.11" + - "3.12" - "3.13" - "3.14" services: @@ -120,7 +122,10 @@ jobs: cache-dependency-glob: "**/pyproject.toml" - run: uv python install ${{ matrix.python-version }} - run: uv python pin ${{ matrix.python-version }} - - run: uv sync --all-extras --no-install-project --resolution lowest-direct + # --no-build: a floor with no wheel for this interpreter must fail here rather + # than quietly compile its sdist. Without it the leg passes on a floor that + # still breaks anyone installing into an image with no build toolchain. + - run: uv sync --all-extras --no-install-project --resolution lowest-direct --no-build # fastapi's floor pulls a starlette whose TestClient predates httpx2 support. # Installed here rather than declared in the dev group: at the resolved-highest # end starlette takes the httpx2 that group already declares, and adding httpx diff --git a/pyproject.toml b/pyproject.toml index 4201234..7422f43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,10 +36,10 @@ dependencies = [ # Not imported here: faststream pulls pydantic through fast-depends[pydantic], which allows it # back to 1.x. FastStream's serializer calls model_dump, so publishing a model raises # AttributeError on pydantic 1 — v2 is a real requirement of ours, not a preference. The two - # marked floors are wheel coverage: pydantic-core ships no cp313 wheel before pydantic 2.8 - # and no cp314 wheel before 2.12. + # marked floors are wheel coverage: pydantic-core ships no cp313 wheel before pydantic 2.8.1 + # (2.8.0 carries pydantic-core 2.20.0, which has none) and no cp314 wheel before 2.12. "pydantic>=2; python_version < '3.13'", - "pydantic>=2.8; python_version == '3.13'", + "pydantic>=2.8.1; python_version == '3.13'", "pydantic>=2.12; python_version >= '3.14'", # 4.12.2, not 4.12.0: pydantic requires >=4.12.2 on 3.13+, and pinning 4.12.0 drags pydantic # back to a build whose pydantic-core has no cp313 wheel either.