raptor.conformance.freethreading

raptor.conformance.freethreading#

Free-threaded CPython conformance harness (the FT-* row family).

Pure standard library, importable on every interpreter. pytest is imported function-locally, exactly as raptor.conformance.interop does, so the rest of raptor.conformance stays importable without it.

The harness is written for reuse by every package in the family that ships a module to be run under 3.13t / 3.14t. Its pieces:

  • require_free_threaded() – skip on a GIL build, fail when the GIL state is forced from outside (-X gil=... or PYTHON_GIL): a forced state hides a missing FREE_THREADED declaration, so a run under it certifies nothing.

  • hammer() – N threads released together by a barrier.

  • assert_gil_free() (row class FT-1) – import a module in a clean subprocess under -W error::RuntimeWarning and require that the GIL is still off afterwards.

  • measure_loss() / canary_python() / require_not_vacuous() (row class FT-2) – a planted race that the schedule must expose. A schedule that cannot lose updates on a known-racy counter cannot certify that a real counter is race-free, so the run is RED as vacuous, never green. A package supplies its own compiled canary (conventionally _unsynchronised_bump) through measure_loss().

FT-3..FT-6 (global state, distinct objects, shared-object misuse, GPU) are package-specific; packages build them from hammer() and register their row ids with declare_ft_row() / register_ft_row().

Module Attributes

CANARY_THREADS

Default hammer shape of the vacuity canary (threads x iterations per thread).

MIN_LOST_FRACTION

A canary that loses less than this fraction of its updates is vacuous.

CANARY_GAP

Busy-loop steps between the canary's read and its write.

FT_ROWS

row_id -> FtRowDecl.

Functions

assert_ft_rows_complete(…)

Assert every FT row owned by owner_repo was collected.

assert_gil_free(…)

FT-1: importing module_name leaves the GIL disabled.

canary_python(…)

FT-2 canary: an unsynchronised read-modify-write of one shared value, with gap busy steps between the read and the write.

declare_ft_row(…)

Declare a package's FT row ahead of its test (idempotent for equal args).

free_threaded_problem()

Return why this process cannot certify free-threading, or None.

hammer(…)

Run fn() iterations times on each of threads threads.

measure_loss(…)

Hammer a deliberately unsynchronised bump and count lost updates.

register_ft_row(…)

Decorator marking a test as covering declared FT row row_id.

require_free_threaded()

Skip on a GIL build; FAIL when the GIL state is forced from outside.

require_not_vacuous(…)

Fail (RED, never skip) unless the canary lost at least min_lost.

Classes

CanaryResult

Outcome of one planted-race measurement.

FtRowDecl

One declared free-threading row (owner_repo carries its test).