Skip to content

Conversation

@rgommers
Copy link
Contributor

Opening as draft to discuss. It looks like PEP 793 usage works without any issues - which is what I wanted to check - I think we can integrate this now since that PEP is accepted. We can also wait until 3.15 is further along and we can add that in one or a couple of CI jobs.

There does seem to be an issue with test_sdist.py::test_symlinks on Windows, not immediately sure what's going on there yet.

@rgommers rgommers added the tests label Jan 13, 2026
@dnicolodi
Copy link
Member

The test failure with CPython 3.15 is weird. From far it looks like an issue in meson sdist. However, why would we want to test the Python API in meson-python? AFAICT the old API is not going away any time soon, thus we can keep relaying on it in the meson-python tests.

python:
- '3.9'
- '3.14'
- '3.15.0-alpha.3'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to set allow-prereleases: true in the actions/setup-python uses and specify this simply as 3.15 so we don't need to do anything when Python 3.15 is released.

@rgommers
Copy link
Contributor Author

AFAICT the old API is not going away any time soon, thus we can keep relaying on it in the meson-python tests.

It is for the stable ABI, most likely. We'll get either PEP 803 or PEP 809, which changes the stable ABI to support free-threading. After reading both of those PEPs it was still unclear to me whether the old Limited API is still supported on 3.15, and the answer seems to be "no". See this message, and in particular this part:

image

Now it's still early days and lots of things aren't working yet for 3.15, but I'm starting to work towards that free-threading stable ABI support. And I think we have backwards compat impact for the meson-python with-GIL limited API support as well, it maybe stop working. Now of course everyone today is still targets cp311_abi3 or something around that version, so cp315_abi3 isn't very important yet, but it could bite our users when building from source on a 3.15 interpreter.

Either way, there will be things for us to do that require using PyModExport. I just added it to one random test package for now where that looked easy. I can delay it and/or move it to any other test package. But we'll need it within a few months somewhere I believe.

@rgommers
Copy link
Contributor Author

It might also make sense to add it to one of the tests in the meson test suite first. It does work fine today, so also not urgent, but it'd be nice to cover it. @eli-schwartz any preference on when/where to do this?

@dnicolodi
Copy link
Member

AFAICT the old API is not going away any time soon, thus we can keep relaying on it in the meson-python tests.

It is for the stable ABI, most likely.

I haven't been following these discussions, but I fail to see how something can be called "stable ABI" if things get removed from it. I thought that things can be added to the limited API but cannot be removed. If the old module initialization interface goes away in CPython 3.15, packages building against the limited API will need to have two stable ABI wheels: one for the Python from the minimum versions supported to 3.14 and one for 3.15 onward. Not impossible to do, but it seems to be defeating the purpose.

@rgommers
Copy link
Contributor Author

I haven't been following these discussions, but I fail to see how something can be called "stable ABI" if things get removed from it

To be clear: the ABI itself won't be broken (for backwards compat reasons), so a cp311_abi3 wheel will continue to work. But that does not mean it's allowed to target that same ABI via the limited API on 3.15+.

I thought that things can be added to the limited API but cannot be removed

That was the position for a very long time indeed, but the PEPs make the point that "forever" is too long a support window . IIRC PEP 809 wants to set it to 10 years. Either way, no existing APIs are removed in 3.15, just new ones added - and what is removed is the ability to target the stable ABI on a 3.15 interpreter using the old APIs.

The other change is because adding free-threading to the current API/ABI isn't possible, hence the new one which will work for both free-threaded and with-GIL interpreters.

The PEPs are still confusing and need more clarification on this stuff. I'm in the middle of re-reading them to have a clearer opinion on which of them I'd prefer.

@eli-schwartz
Copy link
Member

Broadly speaking, the thing about the API / ABI split here is,

It is unreasonable and irrational to require a software project to support "everything, forever". But python has a stable ABI because the point of a stable ABI is that you can build binaries and the binaries keep working in theory forever. Users get binaries and binaries breaking is awkward and inconvenient, but source code is for developers and developers can and do live with the need to update source code as the years go by.

On Linux, glibc is the same way, a bit. It hasn't broken ABI in decades and doesn't intend to ever again. But sometimes functions are determined to have always been a very bad idea, or be buggy and need to be changed in backwards incompatible ways. Every function that existed in the past is still available via the ABI, if an existing binary used it, but some of them no longer exist in the headers.

It's okay in CPython land to break the limited API -- it is limited because it doesn't include version specific functions, only functions that belong to the stable ABI. Note the limited API is the limited API, not the stable API, for a reason.

Sometimes, it's also unreasonable and irrational to require a software project to support "all ABI, forever". Not always, as glibc demonstrates, but not all projects are glibc and cannot ever break for any reason or the entire universe collapses. Since a CPython installation is self consistent and needs to be reinstalled from scratch on major upgrades anyway (it is unreasonable and irrational to reinstall an operating system from scratch to break glibc ABI, as it would be the same as telling people their system is no longer an amd64 CPU system and needs to be wiped and re-imaged as an amd64xxx CPU system) -- a CPython 3.14 -> 3.15 bump can break the stable ABI if the advantages are "worth it", and the net effect is just that abi3 wheels cannot be freshly installed.

So in practice, the reason CPython offers a stable ABI isn't the reason most software libraries offer a stable ABI with a stable soname, which is "don't need to rebuild some large fraction of the world after updating", but really is solely limited to "saving developer time when needing to upload 70+ time-consuming wheels to PyPI".

And for that purpose, a "forever" ABI isn't actually necessary or interesting, but an ABI that works in units of ten years worth of CPython releases serves the same purpose quite well.

Things came to a head in CPython land because they aren't glibc and they did dig themselves into a hole by designing an ABI decades ago that is incompatible with today's interest in free-threading. These things happen. If the pain of breaking ABI is bad enough, you maintain two fused ABIs until the end of time so that binaries built in 1990 still run in 2050, but CPython isn't that desperate and would rather just have a clean break. The question is then, how to do it.

  • use the old ABI name (abi3) but change what it means depending on python version -- ugly, but some people are really attached to the idea that if you just don't change the name then nobody will realize you broke ABI
  • implement a new ABI name (abi4) and have CPython look for the ABI(s) that it supports

Both competing proposals also say that during a transition period python 3.15 - 3.16 (17?) non-freethreading should be capable of loading both ABIs, although there's no consensus of whether to do this via black magic or actual ABI tagging , so this isn't a real distinction between the two.

The latter proposal uniquely suggests that since the problem came up once already we should admit that it's going to happen again too, and CPython should commit to having a process for bumping the ABI name and deprecating the old ABI. And if they're already doing that then they can also commit to keeping the API stable in those time blocks

@eli-schwartz
Copy link
Member

It might also make sense to add it to one of the tests in the meson test suite first. It does work fine today, so also not urgent, but it'd be nice to cover it. @eli-schwartz any preference on when/where to do this?

Once 3.15 is in rc1 and cannot change. I assume that this just entails adding an #if preprocessor check on the CPython version and using different source code for the entrypoint for python >= 3.15. Can be done for any existing python module file, I guess.

@rgommers
Copy link
Contributor Author

Once 3.15 is in rc1 and cannot change.

👍🏼 thanks, I'll set myself a reminder somewhere in May/June.

I assume that this just entails adding an #if preprocessor check on the CPython version and using different source code for the entrypoint for python >= 3.15.

Yes indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants