mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-129033: Remove _Py_InitializeMain() function (#129034)
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
parent
c463270c73
commit
07c3518ffb
7 changed files with 15 additions and 153 deletions
|
@ -1946,89 +1946,13 @@ Py_GetArgcArgv()
|
|||
|
||||
See also :c:member:`PyConfig.orig_argv` member.
|
||||
|
||||
Delaying main module execution
|
||||
==============================
|
||||
|
||||
Multi-Phase Initialization Private Provisional API
|
||||
==================================================
|
||||
In some embedding use cases, it may be desirable to separate interpreter initialization
|
||||
from the execution of the main module.
|
||||
|
||||
This section is a private provisional API introducing multi-phase
|
||||
initialization, the core feature of :pep:`432`:
|
||||
|
||||
* "Core" initialization phase, "bare minimum Python":
|
||||
|
||||
* Builtin types;
|
||||
* Builtin exceptions;
|
||||
* Builtin and frozen modules;
|
||||
* The :mod:`sys` module is only partially initialized
|
||||
(ex: :data:`sys.path` doesn't exist yet).
|
||||
|
||||
* "Main" initialization phase, Python is fully initialized:
|
||||
|
||||
* Install and configure :mod:`importlib`;
|
||||
* Apply the :ref:`Path Configuration <init-path-config>`;
|
||||
* Install signal handlers;
|
||||
* Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout`
|
||||
and :data:`sys.path`);
|
||||
* Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`;
|
||||
* Import the :mod:`site` module;
|
||||
* etc.
|
||||
|
||||
Private provisional API:
|
||||
|
||||
* :c:member:`PyConfig._init_main`: if set to ``0``,
|
||||
:c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
|
||||
|
||||
.. c:function:: PyStatus _Py_InitializeMain(void)
|
||||
|
||||
Move to the "Main" initialization phase, finish the Python initialization.
|
||||
|
||||
No module is imported during the "Core" phase and the ``importlib`` module is
|
||||
not configured: the :ref:`Path Configuration <init-path-config>` is only
|
||||
applied during the "Main" phase. It may allow to customize Python in Python to
|
||||
override or tune the :ref:`Path Configuration <init-path-config>`, maybe
|
||||
install a custom :data:`sys.meta_path` importer or an import hook, etc.
|
||||
|
||||
It may become possible to calculate the :ref:`Path Configuration
|
||||
<init-path-config>` in Python, after the Core phase and before the Main phase,
|
||||
which is one of the :pep:`432` motivation.
|
||||
|
||||
The "Core" phase is not properly defined: what should be and what should
|
||||
not be available at this phase is not specified yet. The API is marked
|
||||
as private and provisional: the API can be modified or even be removed
|
||||
anytime until a proper public API is designed.
|
||||
|
||||
Example running Python code between "Core" and "Main" initialization
|
||||
phases::
|
||||
|
||||
void init_python(void)
|
||||
{
|
||||
PyStatus status;
|
||||
|
||||
PyConfig config;
|
||||
PyConfig_InitPythonConfig(&config);
|
||||
config._init_main = 0;
|
||||
|
||||
/* ... customize 'config' configuration ... */
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
PyConfig_Clear(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
/* Use sys.stderr because sys.stdout is only created
|
||||
by _Py_InitializeMain() */
|
||||
int res = PyRun_SimpleString(
|
||||
"import sys; "
|
||||
"print('Run Python code before _Py_InitializeMain', "
|
||||
"file=sys.stderr)");
|
||||
if (res < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ... put more configuration code here ... */
|
||||
|
||||
status = _Py_InitializeMain();
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
}
|
||||
This separation can be achieved by setting ``PyConfig.run_command`` to the empty
|
||||
string during initialization (to prevent the interpreter from dropping into the
|
||||
interactive prompt), and then subsequently executing the desired main module
|
||||
code using ``__main__.__dict__`` as the global namespace.
|
||||
|
|
|
@ -1375,3 +1375,7 @@ Removed
|
|||
|
||||
* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
|
||||
bases was deprecated since 3.12 and now raises a :exc:`TypeError`.
|
||||
|
||||
* Remove the private ``_Py_InitializeMain()`` function. It was a
|
||||
:term:`provisional API` added to Python 3.8 by :pep:`587`.
|
||||
(Contributed by Victor Stinner in :gh:`129033`.)
|
||||
|
|
|
@ -25,9 +25,6 @@ PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs(
|
|||
PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
|
||||
const PyConfig *config);
|
||||
|
||||
// Python 3.8 provisional API (PEP 587)
|
||||
PyAPI_FUNC(PyStatus) _Py_InitializeMain(void);
|
||||
|
||||
PyAPI_FUNC(int) Py_RunMain(void);
|
||||
|
||||
|
||||
|
|
|
@ -1274,24 +1274,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
}
|
||||
self.check_all_configs("test_init_run_main", config, api=API_PYTHON)
|
||||
|
||||
def test_init_main(self):
|
||||
code = ('import _testinternalcapi, json; '
|
||||
'print(json.dumps(_testinternalcapi.get_configs()))')
|
||||
config = {
|
||||
'argv': ['-c', 'arg2'],
|
||||
'orig_argv': ['python3',
|
||||
'-c', code,
|
||||
'arg2'],
|
||||
'program_name': './python3',
|
||||
'run_command': code + '\n',
|
||||
'parse_argv': True,
|
||||
'_init_main': False,
|
||||
'sys_path_0': '',
|
||||
}
|
||||
self.check_all_configs("test_init_main", config,
|
||||
api=API_PYTHON,
|
||||
stderr="Run Python code before _Py_InitializeMain")
|
||||
|
||||
def test_init_parse_argv(self):
|
||||
config = {
|
||||
'parse_argv': True,
|
||||
|
@ -1768,7 +1750,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
|
||||
def test_init_set_config(self):
|
||||
config = {
|
||||
'_init_main': 0,
|
||||
'bytes_warning': 2,
|
||||
'warnoptions': ['error::BytesWarning'],
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Remove the private ``_Py_InitializeMain()`` function. It was a
|
||||
:term:`provisional API` added to Python 3.8 by :pep:`587`. Patch by Victor
|
||||
Stinner.
|
|
@ -1818,7 +1818,6 @@ static int test_init_set_config(void)
|
|||
PyConfig config;
|
||||
PyConfig_InitIsolatedConfig(&config);
|
||||
config_set_string(&config, &config.program_name, PROGRAM_NAME);
|
||||
config._init_main = 0;
|
||||
config.bytes_warning = 0;
|
||||
init_from_config_clear(&config);
|
||||
|
||||
|
@ -1828,12 +1827,6 @@ static int test_init_set_config(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Finish initialization: main part
|
||||
PyStatus status = _Py_InitializeMain();
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -2089,33 +2082,6 @@ static int test_init_run_main(void)
|
|||
}
|
||||
|
||||
|
||||
static int test_init_main(void)
|
||||
{
|
||||
PyConfig config;
|
||||
PyConfig_InitPythonConfig(&config);
|
||||
|
||||
configure_init_main(&config);
|
||||
config._init_main = 0;
|
||||
init_from_config_clear(&config);
|
||||
|
||||
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
|
||||
int res = PyRun_SimpleString(
|
||||
"import sys; "
|
||||
"print('Run Python code before _Py_InitializeMain', "
|
||||
"file=sys.stderr)");
|
||||
if (res < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyStatus status = _Py_InitializeMain();
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
return Py_RunMain();
|
||||
}
|
||||
|
||||
|
||||
static int test_run_main(void)
|
||||
{
|
||||
PyConfig config;
|
||||
|
@ -2473,7 +2439,6 @@ static struct TestCase TestCases[] = {
|
|||
{"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv},
|
||||
{"test_init_read_set", test_init_read_set},
|
||||
{"test_init_run_main", test_init_run_main},
|
||||
{"test_init_main", test_init_main},
|
||||
{"test_init_sys_add", test_init_sys_add},
|
||||
{"test_init_setpath", test_init_setpath},
|
||||
{"test_init_setpath_config", test_init_setpath_config},
|
||||
|
|
|
@ -1505,18 +1505,6 @@ Py_Initialize(void)
|
|||
}
|
||||
|
||||
|
||||
PyStatus
|
||||
_Py_InitializeMain(void)
|
||||
{
|
||||
PyStatus status = _PyRuntime_Initialize();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
return pyinit_main(tstate);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
finalize_modules_delete_special(PyThreadState *tstate, int verbose)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue