Revert Python 3.13 C API Incompatible Changes causing most troubles


My C API: My plan to clarify private vs public functions in Python 3.13 uses Python 3.13 beta 1 (May 2024) as deadline to make most C extensions compatible with Python 3.13.

Problem: I wasn’t prepared for the number of people eagger to test their project on Python 3.13 alpha 1 as soon as it was released. Some people are working on porting their own code to Python 3.13, whereas others are blocked by dependencies not compatible yet. For Python 3.12, it took months to get Cython (7 months) and numpy (10 months) to become compatible (with a release), and apparently people were fine with this pace. I expected to have 6 months to go through issues and make decisions on a case by case basis. But Cython was made compatible with Python 3.13 (alpha1) in 1 week! Well, for the Cython case, becoming compatible mostly means “disable optimizations” sadly. I don’t want Cython (or other projects) to become slower.

Overall, it’s great that people test Python 3.13 alpha 1! I love that, getting feedback as soon as possible! I want to encourage that and help people who are going through issue.

I’m still bug triaging C API reports, whereas some people ask to get Python 3.13 being fixed “right now”. My plan is about designing public C API to replace removed privated functions, but this work takes time since we want to design “future proof” API which cover most use cases, expose less implementation details, and following the latest C API guidelines. It’s not just “take the private API and put it in the public C API”: even if new public functions are added, they will not be drop-in replacements (there might be more work than “remove the underscore prefix”).

I tried to communicate as much as I can in advance about my plan removing private C functions. Now that the changes are done, the impact is known better, and we should reevaluate the situation with these new information.

Another problem is that it’s unclear to me how C API decisions are taken. Latest C API questions to the Steering Council were delegated to the future C API Working Group, but the Working Group doesn’t exist yet.

So well, let me propose concrete actions.

What should be done right now:

What should be done next:

  • For removed functions which impact at least one project but we decide to not revert, document a solution in What’s New in Python 3.13 (even if the function was “private”, usually we don’t document changes related to private APIs). I expected the existing public C API to be complete enough, but the devil is in the details, and “it’s complicated”. Some functions are only available in the private/internal C API, there is “no good” replacement in the public C API. Well, that’s the part that I’m trying to fix.
  • Add better public C API function to replace private C API functions.
  • Help projects to migrate to better public C API functions.

What can be done in the long term:

  • Clarify what _Py prefix means: does it mean “can be changed anytime, no backward compatibility”? Or does mean “it depends…”?
  • Design a new approach to introduce incompatible C API changes. IMO the most practical one would be to introduce the concept of a “compatibility version” and let C extensions opt-in for “future” incompatible changes. It may give more control on who is impacted and when. For example, you can target the “C API version 3.15” and you will be impacted by all planned changes, especially deprecated functions scheduled for removal.
  • Design guidelines on how to introduce incompatible changes.

The overall plan on private APIs was done in the frame of the private API contract:

Names prefixed by an underscore, such as _Py_InternalState, are private API that can change without notice even in patch releases.

Well. That’s the theory, and the practice shows me that users have “different expectations”. Apparently, we have to update/complete this contract…

If we revert private C API function removals, does it mean that these private functions become part of the public C API and have to stay forever, be documented and tested? Or would they move back to their previous state: not supported and “can change anything (which includes being removed)”?

See also:


Looks like this should have been a PEP from the start.

I have been giving my answers to the questions you ask here for a long time now. Maybe it is time to start collecting the options & opinions in a single place?


I think that it is good to change or remove private API if there is a better (or not worse) alternative.

It is better if the alternative exists for a long time, so you can switch your code to the alternative on all supported Python versions. pythoncapi-compat can compensate this.

1 Like

Update: Following the announced plan, I reverted 50 private APIs which were removed in Python 3.13 alpha1. These APIs will be available again in the incoming Python 3.13 alpha2 (scheduled next Tuesday).

Details: Is Python 3.13 going to be Python 4? - #29 by vstinner