You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Remove _Py_InitializeMain() private function #129033
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.
_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().
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.
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:
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.
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?
Activity
pythongh-129033: Remove _Py_InitializeMain() function
pythongh-129033: Remove _Py_InitializeMain() function
vstinner commentedon Jan 19, 2025
cc @ncoghlan @ericsnowcurrently
vstinner commentedon 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 commentedon Jan 20, 2025
Makes sense to me. If an embedding application wants to split up interpreter initialisation and main module execution they can:
run_commandduring initialisation__main__.__dict__latergh-129033: Remove _Py_InitializeMain() function (#129034)
pythongh-129033: Remove _PyInterpreterState_SetConfig() function
pythongh-129033: Remove _PyInterpreterState_SetConfig() function
gh-129033: Remove _PyInterpreterState_SetConfig() function (#129048)
pythongh-129033: Remove _Py_InitializeMain() function (python#129034)
pythongh-129033: Remove _PyInterpreterState_SetConfig() function (pyt…
pythongh-129033: Remove dead code in test.support.has_no_debug_ranges()
gh-129033: Remove dead code in test.support.has_no_debug_ranges() (#1…
pythongh-129033: Remove dead code in test.support.has_no_debug_ranges…
pythongh-129033: Remove dead code in test.support.has_no_debug_ranges…
[3.14] gh-129033: Remove dead code in test.support.has_no_debug_range…
[3.14] pythongh-129033: Remove dead code in test.support.has_no_debug…
kovidgoyal commentedon 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 commentedon Dec 8, 2025
Hi,
First of all, this issue is closed. Would you mind to open a new issue?
Right, https://docs.python.org/3.13/c-api/init_config.html#multi-phase-initialization-private-provisional-api was a Provisional API:
@kovidgoyal:
I just ran a code search on PyPI top 15,000 projects and it returns a single match in orjson which is irrelevant:
I cannot find PyOxidizer and bypy with my methodology. I'm not sure why.
Would you mind to elaborate your use case? Do you use such meta importer to import stdlib modules?
Programs/_freeze_module.cstill 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 commentedon Dec 8, 2025