IMO the nogil project is likely to fail if we don’t offer a “simple” solution to distribute C extensions working on regular (GIL) Python build and nogil Pyhon build. The stable ABI sounds like a good solution since it already exists and partially solves the use case. But as you explained, the current ABI still has some flaws: it still “leaks” some implementation details which make it incompatible with nogil build ![]()
IMO the stable ABI is not widely adopted simply because it’s not the default in distutils, setuptools, poetry, etc. Switch the default to stable ABI, and it’s likely that it will become way more widely used ![]()
What I don’t get is how can a C extension maintainer support nogil and Python 3.12 with the stable ABI? I don’t think that a single binary fits all use cases, since nogil requires calling new functions at the ABI level, functions only available on Python 3.13. I suppose that on PyPI, for each platform/architecture, two binaries are needed:
- Binary for Python >= 3.13: compatible with nogil
- Binary for Python <= 3.12: incompatible with nogil
What happens with a stable ABI compiled on Python 3.12 is used on Python 3.13 nogile build? Crash? Is it slower and may crash if run for days? Or is the behavior just undefined?
Can packaging tooling be updated to handle “nogil” and ship 2 binaries on PyPI instead of 1?
Honestly, the nogil change sounds big enough to motivate creating a new abi4 version. Currently, the stable ABI is called abi3 since Python 3.2 (2011). Since abi3, many missing features were discovered in the limited C API and the stable ABI. So when you say “abi3”, just the name doesn’t say anything about which Python versions are supported, as Sam explained, you must also specify the target version of the limited C API. Hopefully, the version is part of the full wheel binary package filename.
Not only abi4 would add features needed by nogil, but also avoid checking the version to know what’s available or missing. Well, I expect that Python 3.14 will add again new functions to the stable ABI. But abi4 would mean “compatible with nogil build”… and also “not compatible with Python 3.12 and older”.
That’s maybe what people expected by “removing the GIL will require Python 4 (incompatible major version)”. People just misunderstood that only the stable ABI major version should not change, not the Python version ![]()
Obviously, abi3 will still be supported by Python 3.13: supporting it is free (already implemented). Support for Python 3.12 and older stays. For there is nothing like Python 2 to Python 3 “only way only” migration. Here the migration towards abi4 can be done incrementally, on demand when supporting nogil build is “needed”. And if my previous paragraph makes sense, we can easily ship abi3 and abi4 binary wheels of the same C extension to support all Python versions.
Py_SIZE() function/macro has issues: see Py_SIZE is not useful · Issue #10 · capi-workgroup/problems · GitHub
We should consider fixing it before adding it to a stable ABI.
We should expose it as a macro and a function for programming languages and use cases unable to use macros. For example, the vim text editor only uses dlsym() to load libpython symbols, it cannot access macros, even if it’s written in C.
Note: I would prefer Py_IsImmortal() name ![]()