maturin-action icon indicating copy to clipboard operation
maturin-action copied to clipboard

Create 3.14t wheels by default

Open ngoldbaum opened this issue 4 months ago • 3 comments

Over in https://github.com/gcanat/video_reader-rs/issues/70 I noticed that video_reader-rs wasn't uploading cp314t wheels.

It looks like they're using a vanilla version of the action with no customization about building an explicit python version:

https://github.com/gcanat/video_reader-rs/blob/da2c7c905bdf324a9dca332060e410188f9eca39/.github/workflows/build.yml#L52-L63

That makes me suspect this is coming down to the defaults in maturin-action. Is that the case?

ngoldbaum avatar Jul 30 '25 15:07 ngoldbaum

Hey @ngoldbaum, fancy seeing you here... I came here looking to ask a similar question. Please bear with me as I suspect you already know most of this. I'm just posting to summarize the blockers I see toward enabling free-threaded builds automatically.

It seems that the project in question used your linked example to enable 3.14t builds:

       - name: Build wheels
         uses: PyO3/maturin-action@v1
         with:
           target: ${{ matrix.platform.target }}
-          args: --release --out dist --find-interpreter
+          args: --release --out dist --interpreter '3.9 3.10 3.11 3.12 3.13 3.13t 3.14 3.14t pypy3.9 pypy3.10 pypy3.11'

But this ultimately depends on the env having the specified versions (namely 3.13t and 3.14t in this case) present. So, those trying to opt-into free-threaded builds should really be mindful about the python versions (and corresponding cpy dev headers) available for the targeted platform.

This inquiry is further complicated by abi3 wheels. As https://github.com/PyO3/maturin/issues/2772 points out, maturin currently (at this time) lacks the intuition to make separate free-threaded builds when a abi3 feature is enabled. This intuition already exists for PyPy builds when a abi3 feature is enabled, so its not an unrealistic expectation.

I also suspect that maturin --find-interpreter may also need to account for free-threaded versions of Python.

Conclusion

As for making free-threaded builds automatically part of the default maturin-action behavior, I don't think this is currently achievable. Just as a reminder, free-threaded builds are still an explicit opt-in capability in pyo3 (see pyo3 docs). I'm guessing that maturin would have to

  1. somehow detect when all modules have the Py_MOD_GIL slot set to Py_MOD_GIL_NOT_USED
  2. trust (or "assume" depending on your perception) that all #[pyclass]es are thread safe.

This would probably be more easily done if/when free-threaded support becomes enabled by default (something the current pyo3 docs imply is planned for the future).

2bndy5 avatar Nov 26 '25 10:11 2bndy5

As for making free-threaded builds automatically part of the default maturin-action behavior, I don't think this is currently achievable. Just as a reminder, free-threaded builds are still an explicit opt-in capability in pyo3 (see pyo3 docs). I'm guessing that maturin would have to somehow detect when all modules have the Py_MOD_GIL slot set to Py_MOD_GIL_NOT_USED trust (or "assume" depending on your perception) that all #[pyclass]es are thread safe. This would probably be more easily done if/when free-threaded support becomes enabled by default (something the current pyo3 docs imply is planned for the future).

I don't understand this logic. What's wrong with building wheels that reenable the GIL on import (i.e. the pymodules don't declare support)?

Cibuildwheel currently builds 3.14t wheels unless users explicitly opt out. This means that some projects uploaded wheels that do not declare free-threaded support. IMO that's fine since it still fixes build issues for users who want to experiment. I think errors caused by a missing build environment are strictly less user friendly than a runtime warning telling users a module doesn't support the free-threaded build. Even more so because there's an escape hatch for the GIL being reenabled at runtime: set PYTHON_GIL=0.

ngoldbaum avatar Dec 01 '25 20:12 ngoldbaum

What's wrong with building wheels that reenable the GIL on import (i.e. the pymodules don't declare support)?

This could be described as "unexpected behavior" by consumers that try experimenting with free-threaded Python.

Maturin still needs some proper way of detecting when the GIL is disabled (disregarding thread-safety for classes), even if only to output a warning in the build log.

Cibuildwheel currently builds 3.14t wheels unless users explicitly opt out.

I was aiming for correctness. I wasn't comparing the build experience/process to cibuildwheel.

Much of what was stated after this sentence seems opinionated, so I'll just leave that as a difference of opinions.

escape hatch for the GIL being reenabled at runtime: set PYTHON_GIL=0.

Would that cause an error for modules that don't properly support free-threaded Python? I've never actually tried this.

I imagine errors related to classes that are not thread safe would be much less helpful.

2bndy5 avatar Dec 02 '25 00:12 2bndy5