python icon indicating copy to clipboard operation
python copied to clipboard

Provide 3.13t & 3.14t images

Open lysnikolaou opened this issue 3 months ago • 9 comments

Since #947 has been closed by the OP, I thought I'd reopen this here, since the free-threaded build is now a fully-supported build as of PEP 779.

Is there an appetite for providing 3.14t (and maybe also 3.13t, but certainly not necessary) images? If yes, we can certainly offer support with doing the necessary changes for that.

lysnikolaou avatar Oct 06 '25 09:10 lysnikolaou

I think https://github.com/docker-library/python/issues/947#issuecomment-3010381261 is still the most reflective of our current state (the build matrix is large, the compilation is heavy, and this is essentially asking us to double it all for 3.13+):

We could shrink the impact by doing "clever" things like only supporting "nogil" on a limited set of architectures, a limited set of base distributions, etc, but ultimately any choice we make there is definitely going to cause some amount of friction (both for us in maintaining and explaining the line, and for users who get to navigate the line).

We could also consider just including both in the default images, but I doubt that's going to be a popular choice either (and doesn't decrease the compilation burden, just obfuscates it). Ultimately it would be really interesting if this could be an entirely runtime determined value (or some way of having two binaries compiled concurrently and using linking cleverly so that they share most of the final binary size in shared libraries), but that's probably also a tall order.


https://github.com/docker-library/python/issues/947#issuecomment-3011063975

Technically, it is possible to re-enable the GIL on the free-threaded build by setting the environment variable PYTHON_GIL=1. I don't know if it's intended for something like this.

This is really interesting (because then while we'd still have a large matrix, half of it would be simply FROM python:freethreading [what a mouthful :sob:] + ENV PYTHON_GIL 1), but does make me wonder if this is actually really supported/recommended usage -- if it is, shouldn't core be adjusted to always compile with freethreading enabled and install the binary as python3.14t with a python3.14 symlink or small script wrapper that automatically enables the classic GIL mode? Then we'd have the best of both worlds with no real overhead and only a single image. 🤔

tianon avatar Oct 07 '25 20:10 tianon

While I understand the effort and maintenance burden needed for releasing free threading images, i can hardly understand the problem of job matrix size and compilation. I suppose Microsoft spent a lot more money for sponsoring developer time even last years efforts in "faster cpython" project and they have free runners for OSS projects, not to say how much resources something like brew takes, while Dockerhub cpython images have 1B+ docker pulls which means pretty much infinite bandwidth and uncountable money related.

I really cannot get what 80 additional jobs does anything bad for anybody, or even additional 1000 jobs, as long as the actions and GitHub itself can handle it? But of course, I might not be aware of something serious here.

And, let's be honest, people who desperately need free-threading probably can compile and build their own images, that is not big problem. The problem is, that virtually nobody will do it just for a sake of doing it without official images and end goal is for whole language to migrate (that is how i interpret https://peps.python.org/pep-0703/ and https://peps.python.org/pep-0779/). Python image is being run in uncountable CI/CD jobs, the effort of changing tag to free-threading-someting is very little so it would for sure encourage people to migrate, and if it work seamlessly, probably we would see more of it in production.

Thanks!

rafsaf avatar Oct 09 '25 16:10 rafsaf

Perhaps as a compromise, free-threaded builds could be made available just for:

  • 3.14+ (given that in 3.13 it was still marked as experimental, and anyone wanting to try out free-threading should really be doing so with the latest fixes/changes)
  • The newer of the distro/OS versions - so Alpine 2.22 but not 2.21, Debian trixie but not bookworm, and so on. (Which seems like it would be reasonable given that someone wanting to try out a cutting edge Python feature is probably fine with being on the latest distro version?)

Doing that would add these 4 variants (and the various tags that re-use the same images):

  • 3.14t-trixie
  • 3.14t-slim-trixie
  • 3.14t-alpine3.22
  • 3.14t-windowsservercore-ltsc2025

So would increase the total variants from 40 to 44 (multiplied by the various architectures) - so an increase of 10%. (The Python 3.9 EOL will then reduce it back down to 40 variants)

Albeit for every year that goes by before free-threaded builds become enabled by default, the total builds would increase slightly - though (a) they could still be kept to just the latest distro/OS versions to minimise that, (b) hopefully it will only be a couple of years before the free-threaded project plays out one way or another?

edmorley avatar Oct 09 '25 16:10 edmorley

One other concern/design decision I see mentioned in the prior issue (#947) is that of naming.

It looks like since that discussion other tools have begun to standardise around the t suffix (eg 3.14t):

  • uv: https://docs.astral.sh/uv/concepts/python-versions/#free-threaded-python
  • GitHub Actions's actions/setup-python: https://github.com/actions/setup-python?tab=readme-ov-file#basic-usage
  • pyenv: https://github.com/pyenv/pyenv/commit/3ced1c475150e00dfcda4e8cca71a5670d5087b8

(The t suffix is also what the free-threaded Wheel tag name uses, as well as the python3.14t binary name)

edmorley avatar Oct 09 '25 16:10 edmorley

This is really interesting (because then while we'd still have a large matrix, half of it would be simply FROM python:freethreading [what a mouthful 😭] + ENV PYTHON_GIL 1), but does make me wonder if this is actually really supported/recommended usage -- if it is, shouldn't core be adjusted to always compile with freethreading enabled and install the binary as python3.14t with a python3.14 symlink or small script wrapper that automatically enables the classic GIL mode? Then we'd have the best of both worlds with no real overhead and only a single image. 🤔

Hmm, that wouldn't work unfortunately.

The challenge with a single binary approach is that free-threaded Python uses a different ABI, it's not just a runtime toggle. Extensions built for gil-enabled Python (e.g. cp314 wheels) are incompatible with free-threaded Python (e.g. cp314t wheels) and vice versa.

The PYTHON_GIL environment variable can control GIL behavior within a free-threaded build, but it doesn't make a python3.14t binary ABI-compatible with standard python3.14. You'd still need separate wheel ecosystems regardless of whether the GIL is enabled at runtime.

lysnikolaou avatar Oct 13 '25 12:10 lysnikolaou

Yeah, I realized that after re-reading the other thread and implementing the idea. 😞 :heart:

tianon avatar Oct 13 '25 17:10 tianon

I'm not familiar with the details of the differences between the builds, but there is this notice when I run the free-threading build with some libraries, so is the GIL enabled on a free-threading build functionally the same as a standard build? If so, could we just have a single build and have PYTHON_GIL=1 set by default for backwards compatibility?

<frozen importlib._bootstrap>:491: RuntimeWarning: The global interpreter lock (GIL) has been enabled to load module 'newrelic.packages.wrapt._wrappers', which has not declared that it can run safely without the GIL. To override this behavior and keep the GIL disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.

daveisfera avatar Oct 21 '25 00:10 daveisfera

Yeah, I really don't understand how that automatic fallback can work if they're not ABI compatible. 🤔

tianon avatar Oct 21 '25 18:10 tianon

so is the GIL enabled on a free-threading build functionally the same as a standard build?

No, it still uses the free-threading ABI which is not the same as the regular ABI.

There are discussions to have a unified ABI in the future, it might land in 3.15.

pitrou avatar Oct 21 '25 18:10 pitrou