GeezerVison is showing github.com — Remove _Py_InitializeMain() private function · Issue #129033 · python/cpython
Remove _Py_InitializeMain() private function #129033DescriptionPEP 587 "Python Initialization Configuration" added a "Multi-Phase Initialization Private Provisional API":
The plan was to make the "core phase" more usable. But since Python 3.8, Python doesn't use this "Multi-Phase Initialization" API and I failed to find any user in 3rd party code.
I propose to remove this API in Python 3.14 without any deprecation since the feature was provisional and it's a private API.
Provisional:
A provisional API is one which has been deliberately excluded from the standard library’s backwards compatibility guarantees.
Linked PRs
Activityvstinner commented on Jan 19, 2025 vstinner commented on Jan 19, 2025 _PyInterpreterState_SetConfig() and _PyInterpreterState_GetConfigCopy() can also be removed if _Py_InitializeMain() is removed. PEP 741 "Python Configuration C API" added a public API for that: PyConfig_Set().
ncoghlan commented on Jan 20, 2025 Makes sense to me. If an embedding application wants to split up interpreter initialisation and main module execution they can:
- Pass an empty string in
run_command during initialisation
- Execute the relevant code in
__main__.__dict__ later
kovidgoyal commented on Dec 8, 2025 This totally breaks multi-phase initialization. With no deprecation period and no warning! This code was used in the wild by multiple projects. To name just two that I am personally aware of: PyOxidizer and bypy. Both of these are on github so I dont know how you failed to find them in 3rd party code.
More importantly you have removed this capability without providing any viable alternative. Multi-phase initialization was not only about separating initialization from main module execution. It was also about having a hook point between the "core" and "main" initialization phases of the interpreter. There appears to be no way to do that anymore. Indeed I would argue that the latter is the main use case for multi phase initialization.
This makes it impossible, as far as I can tell, to insert a meta importer into sys.meta_path before the "main" initialization phase. The main initialization phase tries to load the encodings module, so it is now impossible to have this module (and any other modules initialization may depend on) not available on the filesystem as separate py files. My applications that embed python in a larger program rely on bundling all python code into a single mmaped() file containing pre-compiled bytecode for performance.
Furthermore you have removed _Py_MainInitialize() but left PyConfig._init_main. How is one supposed to use _init_main without _Py_MainInitialize()?
Please re-open this and either revert this removal or provide some way to achieve the usecase of enabling embedding applications to override where imports happen during the "main" initialization phase. vstinner commented on Dec 8, 2025 Hi,
First of all, this issue is closed. Would you mind to open a new issue?
This totally breaks multi-phase initialization. With no deprecation period and no warning!
Right, https://docs.python.org/3.13/c-api/init_config.html#multi-phase-initialization-private-provisional-api was a Provisional API:
A provisional API is one which has been deliberately excluded from the standard library’s backwards compatibility guarantees.
@kovidgoyal:
This code was used in the wild by multiple projects. To name just two that I am personally aware of: PyOxidizer and bypy. Both of these are on github so I dont know how you failed to find them in 3rd party code.
I just ran a code search on PyPI top 15,000 projects and it returns a single match in orjson which is irrelevant:
PYPI-2025-09-22/orjson-3.11.3.tar.gz: orjson-3.11.3/include/cargo/pyo3-ffi-0.25.1/src/cpython/pylifecycle.rs: pub fn _Py_InitializeMain() -> PyStatus;
I cannot find PyOxidizer and bypy with my methodology. I'm not sure why.
This makes it impossible, as far as I can tell, to insert a meta importer into sys.meta_path before the "main" initialization phase.
Would you mind to elaborate your use case? Do you use such meta importer to import stdlib modules?
Furthermore you have removed _Py_MainInitialize() but left PyConfig._init_main. How is one supposed to use _init_main without _Py_MainInitialize()?
Programs/_freeze_module.c still uses _init_main = 0. I kept the option for this file which doesn't need the main phase. It's just to "bootstrap" Python build.
I'm sorry that you're affected by these removals, I wasn't aware of any users of this feature. Again, please reply by opening a new issue. kovidgoyal commented on Dec 8, 2025 On Mon, Dec 08, 2025 at 04:17:23AM -0800, Victor Stinner wrote:
vstinner left a comment ( python/cpython#129033)
Hi,
First of all, this issue is closed. Would you mind to open a new issue?
Reacted by Victor Stinner
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|