Skip to content

Add the free-threaded 3.14t build to the pytest matrix in 19 libraries #91

Closed

Description

@lesnik512

Why

The standard, section 6: the test matrix always includes the newest stable CPython minor and that minor's free-threaded build (3.14 and 3.14t today). Only modern-di, httpware, faststream-outbox and lite-bootstrap test under free-threading.

Repos

compose2pod, db-retry, eof-fixer, faststream-concurrent-aiokafka, faststream-redis-timers, modern-di-aiogram, modern-di-aiohttp, modern-di-arq, modern-di-celery, modern-di-fastapi, modern-di-faststream, modern-di-flask, modern-di-grpc, modern-di-litestar, modern-di-pytest, modern-di-starlette, modern-di-taskiq, modern-di-typer, semvertag.

Change

In .github/workflows/_checks.yml, add "3.14t" to the pytest job's python-version matrix. modern-di's workflow is the reference; it also confirms the interpreter is free-threaded with python -c "import sys; assert not sys._is_gil_enabled()" before running the suite. Add the Programming Language :: Python :: Free Threading :: 2 - Beta classifier where the repo wants to advertise it.

A suite that fails under 3.14t is a real finding, not a reason to drop the entry: fix or record an exemption on the standard's table.

Done when

Every repo above runs its pytest job on 3.14t and is green.

Activity

  1. lesnik512 commented on Sep 12, 2026

    @lesnik512
    MemberAuthor

    Status: 17 of the 19 repos have a PR; the other two get exemption rows in #97.

    Probe first, then PRs. Every repo was synced against 3.14.7 free-threaded, every installed distribution imported, and sys._is_gil_enabled() checked afterwards; suites were run where no service container is needed. Fourteen repos were clean. The findings, and how each PR handles them:

    Repo Finding Handling Lift condition
    db-retry SQLAlchemy 2.0.x cyext re-enables the GIL on import DISABLE_SQLALCHEMY_CEXT_RUNTIME=1 on the 3.14t entry only SQLAlchemy 2.1 (declaration landed upstream, sqlalchemy/sqlalchemy#12881)
    faststream-concurrent-aiokafka aiokafka 0.14 has no cp314t wheel; its C codecs re-enable the GIL AIOKAFKA_NO_EXTENSIONS=1 on the 3.14t entry only an aiokafka release with a cp314t wheel that declares free-threading
    modern-di-starlette gc.collect() == 0 invariant fails; bare Starlette already hands the collector the last response's objects on 3.14t because TestClient's worker thread defers refcount releases the invariant now inspects what the collector reclaims and asserts none of it is a container or a scope entry, on both builds; GIL builds still assert zero. Also fixed: the test kept every scope alive, so the old zero check could never fail none needed
    modern-di-arq arq requires redis[hiredis]<6; hiredis re-enables the GIL exemption row, #97 redis/hiredis-py#229
    modern-di-grpc grpcio has no cp314t wheel; cygrpc re-enables the GIL exemption row, #97 grpc/grpc#38762

    The two env workarounds are not exemptions: the entry runs, the assert step confirms the GIL is off, and the other matrix entries keep testing the C extensions. They are recorded here so the lift is not forgotten when #95 derives the matrix.

    Every 3.14t entry runs python -c "import sys, <package>; assert not sys._is_gil_enabled()" before the suite. This imports the package on purpose, one step past the reference: pytest only warns when an import re-enables the GIL, so a bare import sys assert would pass a run that silently went back to GIL mode.

    PRs: modern-python/compose2pod#95, modern-python/db-retry#43, modern-python/eof-fixer#40, modern-python/faststream-concurrent-aiokafka#71, modern-python/faststream-redis-timers#74, modern-python/modern-di-aiogram#20, modern-python/modern-di-aiohttp#25, modern-python/modern-di-celery#20, modern-python/modern-di-fastapi#48, modern-python/modern-di-faststream#49, modern-python/modern-di-flask#20, modern-python/modern-di-litestar#50, modern-python/modern-di-pytest#46, modern-python/modern-di-starlette#25, modern-python/modern-di-taskiq#18, modern-python/modern-di-typer#44, modern-python/semvertag#68, and #97 for the standard.

  2. lesnik512 commented on Sep 12, 2026

    @lesnik512
    MemberAuthor

    All 17 PRs and #97 are merged. Every listed repo except modern-di-arq and modern-di-grpc runs its pytest job on 3.14t and is green; those two carry exemption rows on the standard with the upstream issue that lifts each.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions