Setting up CI#
While you may extend the following instruction to also setup CI on 3.13t, werecommend focusing on 3.14+.
CI setup viasetup-python#
The easiest way to get a free-threaded Python build on a CI runner is with thesetup-python Github Action:
jobs:free-threaded:runs-on:ubuntu-lateststeps:-uses:actions/checkout@...-uses:actions/setup-python@...with:python-version:3.14tCI setup viasetup-uv#
An alternative tosetup-python is to usesetup-uv Github Action:
jobs:free-threaded:runs-on:ubuntu-lateststeps:-uses:actions/checkout@...-uses:astral-sh/setup-uv@...with:python-version:3.14tYou should replace the ellipses with versions for the actions.
Windows CI setup via custom PowerShell#
For installing a free-threaded build of Python on a Windows CI runner(runs-on: windows-latest), you can download and install directly fromhttps://www.python.org/ftp/python/ asshown in the following PowerShell snippet (noting that the free-threadedbinary is namedpython{version}t.exe, where the "t" is for free-"t"hreaded).For more tips see thedocs on silent installation and options onWindows.
jobs:free-threaded:runs-on:windows-lateststeps:-uses:actions/checkout@...-name:custom python install scriptshell:pwshrun:|$pythonInstallerUrl = 'https://www.nuget.org/api/v2/package/python-freethreaded/3.13.1'Invoke-WebRequest $pythonInstallerUrl -OutFile 'python-freethreaded.3.13.1.nupkg'Install-Package python-freethreaded -Scope CurrentUser -Source $pwd$python_dir = (Get-Item((Get-Package -Name python-freethreaded).Source)).DirectoryName$env:path = $python_dir + "\tools;" + $python_dir + "\tools\Scripts;" + $env:PathBuilding free-threaded wheels with cibuildwheel#
cibuildwheel 3.1+ has supportfor building free-threaded wheels on all platforms. If your project releasesnightly wheels, we suggest configuringcibuildwheel to build nightlyfree-threaded wheels.
To ensure wheels are built correctly under cibuildwheel, you will need tospecify the following variables in the environment for the cibuildwheel action:
-name:Build wheelsuses:pypa/cibuildwheel@...env:# enable cpython-freethreading necessary only for 3.13t# CIBW_ENABLE: cpython-freethreadingCIBW_BUILD:cp314t-${{ matrix.buildplat }}As above, replace the ellipses with acibuildwheel version.
You will also likely need to manually pass-Xgil=0 or setPYTHON_GIL=0 inyour shell environment while running tests to ensure the GIL is actuallydisabled during tests, at least until you can register that your extensionmodules support disabling the GIL viaPy_mod_gil and allof your runtime test dependencies do the same. Seethe portingguide for more information about declaring support forfree-threaded python in your extension.
Info
If a dependency of your package does not support free-threading or has notyet done a release which includescp314t wheels, this can be tricky towork around because an environment marker for free-threading does not exist(seethis Discourse thread).Hence it is not possible to special-case free-threading with static metadatainpyproject.toml. It's fine to still uploadcp314t wheels for yourpackage to PyPI; the user may then be responsible for getting thedependency installed (e.g., from a nightly wheel or building thedependency'smain branch from source) if the last release of thedependency doesn't cleanly build from source or doesn't work underfree-threading.
CI Timeouts#
With free-threading deadlocks and hangs are more likely.GitHub action and other Continuous Integration systems often also supports timeouts:timeout-minutes
jobs: test_freethreading: timeout-minutes: 10 steps: - uses: actions/checkout@... ...