Those are good questions, and for the purposes of this PEP I think we should use what we have available now, which is pyperformance’s memory reports. For the next phase, as the PEP mentions, we need to know what people actually care about, and then we need to figure out how to measure that. The pyperformance benchmarks measure fairly well how the pyperformance benchmarks use memory, so it’s not bad for seeing the impact of changes, but it doesn’t necessarily reflect what end users can expect to see.
We don’t have a better answer to that than (POSIX) threading sees in general, for many other programming languages, which is “eeeh, well, uuuhm” and – if you’re lucky – “maybe run this tool and see”. We don’t have tooling like ThreadSanitizer or Thread Safety Analysis like they’re available for C++ (yet), although those tools do work for extension modules.
We do have documentation that tries to answer these things, like Python experimental support for free threading — Python 3.13.2 documentation and https://py-free-threading.github.io/, although I’m sure they can use more work (also, @ngoldbaum mentioned to me that he’s going to try and address some of your questions there.) If people who aren’t familiar with free-threading yet would like to review those and tell us what they’re missing, that would be great :). I’ll add an item to the PEP about good user-facing docs, in addition to the internal docs, although the question is really how much this matters in order to be able to say “this feature is now stable and supported in CPython”.
I haven’t had to touch any Python code myself (other than writing tests), but I haven’t done most of the third-party work. Maybe @ngoldbaum or others from Quansight who’ve worked on that can comment.
The tricky thing with threads, of course, is that you don’t know if something is thread-safe until you discover it is not, by using it (heavily) from multiple threads at the same time. But it is the case that anything in Python code that relies on the GIL isn’t thread-safe, it just had a much lower likelihood of breaking because of the GIL. Would you count finding and fixing those kinds of issues as part of the work to support free-threading?
I think you know this, but I want to point it out explicitly for other readers: undocumented thread-safety guarantees are not guarantees. The GIL does not make Python code thread-safe, undocumented or otherwise. Any Python code that relies on the GIL is likely to already be subtly wrong, free-threading makes it more apparent.
I don’t think we’ve considered this at all. I assumed we would continue to do what we did, except remove mention of the feature as being ‘experimental’. For 3.14 it probably still needs to carry warnings about limited third-party support, not unlike the caveat we had to apply to the 64-bit Windows installer for a long time. Do you think we need to make it more prominent in the installers?
The problem is that we need people to actively test things, so they will need a way to invoke the free-threaded build. Whether we call it experimental or not, they will end up relying on the python-t versions. And the “experimental” phase, per the SC’s acceptance, was to solidify the API design and CPython’s implementation. We think we’re done with that, and we don’t want to make it seem to users that this can break in incompatible ways or suddenly vanish. Once it’s supported, rather than explicitly experimental, PEP 387 applies, etc.
Oh yes, that’s definitely the bulk of the work in extension modules. It’s not always easy, especially if you have complicated shared state. But for most of it, the fixes are relatively easy. It doesn’t require a Sam-level expert. I know, because I fixed some myself
– but also, we have documentation, and a bunch of people fixing things in a whole bunch of projects, all the way to producing free-threaded wheels in some pretty complicated packages, like numpy. It’s definitely some work, but it’s at least somewhat of a paved path now.
Also, the existence of free-threaded Python does not force projects to fix their extension modules. When extension modules don’t declare they support free-threaded Python, they can still be used – they just re-enable the GIL when imported. That will matter to users of the package who do want to use it in a GIL-less free-threaded build, of course, but it’s not nearly as immediate a break as Python 3 was.
And just to tie it to this particular PEP, I do think we need to be clear in our messaging around free-threaded being “supported” in CPython: it does not mean users can expect third-party packages to work. Everywhere we talk about it, we need to be honest about what users can expect from the community in this. As mentioned in the SC acceptance, it will take time to migrate everything… but we have a solid, supported base to get that going, and we can have a nice gradual migration.
That is a fair concern, even if I don’t share it in this case. I think making it clear that PEP 387 applies to free-threaded Python is important for that reason, too: it’s not suddenly going away, but it’s not, at this point, a “forever” guarantee either. (The SC acceptance mentions this, too: in phase II, we can still roll it all back.)
As for the burden on third-party developers, the decision to support free-threaded Python is ultimately up to them. Whether we call it “supported” in CPython or not, work will continue to add free-threading support to more packages, because it really is a desirable feature. I think the question is whether we want to make guarantees to them about the stability of the implementation.