10000 gh-129033: Remove _Py_InitializeMain() function (#129034) · python/cpython@07c3518 · GitHub
[go: up one dir, main page]

Skip to content

Commit 07c3518

Browse files
vstinnerncoghlan
andauthored
gh-129033: Remove _Py_InitializeMain() function (#129034)
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
1 parent c463270 commit 07c3518

File tree

7 files changed

+15
-153
lines changed

7 files changed

+15
-153
lines changed

Doc/c-api/init_config.rst

Lines changed: 8 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,89 +1946,13 @@ Py_GetArgcArgv()
19461946
19471947
See also :c:member:`PyConfig.orig_argv` member.
19481948
1949+
Delaying main module execution
1950+
==============================
19491951
1950-
Multi-Phase Initialization Private Provisional API
1951-
==================================================
1952+
In some embedding use cases, it may be desirable to separate interpreter initialization
1953+
from the execution of the main module.
19521954
1953-
This section is a private provisional API introducing multi-phase
1954-
initialization, the core feature of :pep:`432`:
1955-
1956-
* "Core" initialization phase, "bare minimum Python":
1957-
1958-
* Builtin types;
1959-
* Builtin exceptions;
1960-
* Builtin and frozen modules;
1961-
* The :mod:`sys` module is only partially initialized
1962-
(ex: :data:`sys.path` doesn't exist yet).
1963-
1964-
* "Main" initialization phase, Python is fully initialized:
1965-
1966-
* Install and configure :mod:`importlib`;
1967-
* Apply the :ref:`Path Configuration <init-path-config>`;
1968-
* Install signal handlers;
1969-
* Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout`
1970-
and :data:`sys.path`);
1971-
* Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`;
1972-
* Import the :mod:`site` module;
1973-
* etc.
1974-
1975-
Private provisional API:
1976-
1977-
* :c:member:`PyConfig._init_main`: if set to ``0``,
1978-
:c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
1979-
1980-
.. c:function:: PyStatus _Py_InitializeMain(void)
1981-
1982-
Move to the "Main" initialization phase, finish the Python initialization.
1983-
1984-
No module is imported during the "Core" phase and the ``importlib`` module is
1985-
not configured: the :ref:`Path Configuration <init-path-config>` is only
1986-
applied during the "Main" phase. It may allow to customize Python in Python to
1987-
override or tune the :ref:`Path Configuration <init-path-config>`, maybe
1988-
install a custom :data:`sys.meta_path` importer or an import hook, etc.
1989-
1990-
It may become possible to calculate the :ref:`Path Configuration
1991-
<init-path-config>` in Python, after the Core phase and before the Main phase,
1992-
which is one of the :pep:`432` motivation.
1993-
1994-
The "Core" phase is not properly defined: what should be and what should
1995-
not be available at this phase is not specified yet. The API is marked
1996-
as private and provisional: the API can be modified or even be removed
1997-
anytime until a proper public API is designed.
1998-
1999-
Example running Python code between "Core" and "Main" initialization
2000-
phases::
2001-
2002-
void init_python(void)
2003-
{
2004-
PyStatus status;
2005-
2006-
PyConfig config;
2007-
PyConfig_InitPythonConfig(&config);
2008-
config._init_main = 0;
2009-
2010-
/* ... customize 'config' configuration ... */
2011-
2012-
status = Py_InitializeFromConfig(&config);
2013-
PyConfig_Clear(&config);
2014-
if (PyStatus_Exception(status)) {
2015-
Py_ExitStatusException(status);
2016-
}
2017-
2018-
/* Use sys.stderr because sys.stdout is only created
2019-
by _Py_InitializeMain() */
2020-
int res = PyRun_SimpleString(
2021-
"import sys; "
2022-
"print('Run Python code before _Py_InitializeMain', "
2023-
"file=sys.stderr)");
2024-
if (res < 0) {
2025-
exit(1);
2026-
}
2027-
2028-
/* ... put more configuration code here ... */
2029-
2030-
status = _Py_InitializeMain();
2031-
if (PyStatus_Exception(status)) {
2032-
Py_ExitStatusException(status);
2033-
}
2034-
}
1955+
This separation can be achieved by setting ``PyConfig.run_command`` to the empty
1956+
string during initialization (to prevent the interpreter from dropping into the
1957+
interactive prompt), and then subsequently executing the desired main module
1958+
code using ``__main__.__dict__`` as the global namespace.

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,3 +1375,7 @@ Removed
13751375

13761376
* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
13771377
bases was deprecated since 3.12 and now raises a :exc:`TypeError`.
1378+
1379+
* Remove the private ``_Py_InitializeMain()`` function. It was a
1380+
:term:`provisional API` added to Python 3.8 by :pep:`587`.
1381+
(Contributed by Victor Stinner in :gh:`129033`.)

Include/cpython/pylifecycle.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs(
2525
PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
2626
const PyConfig *config);
2727

28-
// Python 3.8 provisional API (PEP 587)
29-
PyAPI_FUNC(PyStatus) _Py_InitializeMain(void);
30-
3128
PyAPI_FUNC(int) Py_RunMain(void);
3229

3330

Lib/test/test_embed.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,24 +1274,6 @@ def test_init_run_main(self):
12741274
}
12751275
self.check_all_configs("test_init_run_main", config, api=API_PYTHON)
12761276

1277-
def test_init_main(self):
1278-
code = ('import _testinternalcapi, json; '
1279-
'print(json.dumps(_testinternalcapi.get_configs()))')
1280-
config = {
1281-
'argv': ['-c', 'arg2'],
1282-
'orig_argv': ['python3',
1283-
'-c', code,
1284-
'arg2'],
1285-
'program_name': './python3',
1286-
'run_command': code + '\n',
1287-
'parse_argv': True,
1288-
'_init_main': False,
1289-
'sys_path_0': '',
1290-
}
1291-
self.check_all_configs("test_init_main", config,
1292-
api=API_PYTHON,
1293-
stderr="Run Python code before _Py_InitializeMain")
1294-
12951277
def test_init_parse_argv(self):
12961278
config = {
12971279
'parse_argv': True,
@@ -1768,7 +1750,6 @@ def test_init_warnoptions(self):
17681750

17691751
def test_init_set_config(self):
17701752
config = {
1771-
'_init_main': 0,
17721753
'bytes_warning': 2,
17731754
'warnoptions': ['error::BytesWarning'],
17741755
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove the private ``_Py_InitializeMain()`` function. It was a
2+
:term:`provisional API` added to Python 3.8 by :pep:`587`. Patch by Victor
3+
Stinner.

Programs/_testembed.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,6 @@ static int test_init_set_config(void)
18181818
PyConfig config;
18191819
PyConfig_InitIsolatedConfig(&config);
18201820
config_set_string(&config, &config.program_name, PROGRAM_NAME);
1821-
config._init_main = 0;
18221821
config.bytes_warning = 0;
18231822
init_from_config_clear(&config);
18241823

@@ -1828,12 +1827,6 @@ static int test_init_set_config(void)
18281827
return 1;
18291828
}
18301829

1831-
// Finish initialization: main part
1832-
PyStatus status = _Py_InitializeMain();
1833-
if (PyStatus_Exception(status)) {
1834-
Py_ExitStatusException(status);
1835-
}
1836-
18371830
dump_config();
18381831
Py_Finalize();
18391832
return 0;
@@ -2089,33 +2082,6 @@ static int test_init_run_main(void)
20892082
}
20902083

20912084

2092-
static int test_init_main(void)
2093-
{
2094-
PyConfig config;
2095-
PyConfig_InitPythonConfig(&config);
2096-
2097-
configure_init_main(&config);
2098-
config._init_main = 0;
2099-
init_from_config_clear(&config);
2100-
2101-
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
2102-
int res = PyRun_SimpleString(
2103-
"import sys; "
2104-
"print('Run Python code before _Py_InitializeMain', "
2105-
"file=sys.stderr)");
2106-
if (res < 0) {
2107-
exit(1);
2108-
}
2109-
2110-
PyStatus status = _Py_InitializeMain();
2111-
if (PyStatus_Exception(status)) {
2112-
Py_ExitStatusException(status);
2113-
}
2114-
2115-
return Py_RunMain();
2116-
}
2117-
2118-
21192085
static int test_run_main(void)
21202086
{
21212087
PyConfig config;
@@ -2473,7 +2439,6 @@ static struct TestCase TestCases[] = {
24732439
{"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv},
24742440
{"test_init_read_set", test_init_read_set},
24752441
{"test_init_run_main", test_init_run_main},
2476-
{"test_init_main", test_init_main},
24772442
{"test_init_sys_add", test_init_sys_add},
24782443
{"test_init_setpath", test_init_setpath},
24792444
{"test_init_setpath_config", test_init_setpath_config},

Python/pylifecycle.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,18 +1505,6 @@ Py_Initialize(void)
15051505
}
15061506

15071507

1508-
PyStatus
1509-
_Py_InitializeMain(void)
1510-
{
1511-
PyStatus status = _PyRuntime_Initialize();
1512-
if (_PyStatus_EXCEPTION(status)) {
1513-
return status;
1514-
}
1515-
PyThreadState *tstate = _PyThreadState_GET();
1516-
return pyinit_main(tstate);
1517-
}
1518-
1519-
15201508
static void
15211509
finalize_modules_delete_special(PyThreadState *tstate, int verbose)
15221510
{

0 commit comments

Comments
 (0)
0