Skip to content

Commit 6e3807f

Browse files
vstinnershihai1991
authored andcommitted
bpo-38858: Add init_interp_main() subfunction (pythonGH-17347)
Fix new_interpreter() error handling: undo it all if status is an exception.
1 parent 6a31a42 commit 6e3807f

File tree

1 file changed

+109
-103
lines changed

1 file changed

+109
-103
lines changed

Python/pylifecycle.c

Lines changed: 109 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ _Py_LegacyLocaleDetected(int warn)
260260
#endif
261261
}
262262

263+
#ifndef MS_WINDOWS
263264
static const char *_C_LOCALE_WARNING =
264265
"Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
265266
"encoding), which may cause Unicode compatibility problems. Using C.UTF-8, "
@@ -274,6 +275,7 @@ emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
274275
PySys_FormatStderr("%s", _C_LOCALE_WARNING);
275276
}
276277
}
278+
#endif /* !defined(MS_WINDOWS) */
277279

278280
typedef struct _CandidateLocale {
279281
const char *locale_name; /* The locale to try as a coercion target */
@@ -896,123 +898,115 @@ pyinit_core(_PyRuntimeState *runtime,
896898
configuration. Example of bpo-34008: Py_Main() called after
897899
Py_Initialize(). */
898900
static PyStatus
899-
_Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
901+
_Py_ReconfigureMainInterpreter(PyThreadState *tstate)
900902
{
901-
PyConfig *config = &interp->config;
903+
PyConfig *config = &tstate->interp->config;
902904

903905
PyObject *argv = _PyWideStringList_AsList(&config->argv);
904906
if (argv == NULL) {
905907
return _PyStatus_NO_MEMORY(); \
906908
}
907909

908-
int res = PyDict_SetItemString(interp->sysdict, "argv", argv);
910+
int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv);
909911
Py_DECREF(argv);
910912
if (res < 0) {
911913
return _PyStatus_ERR("fail to set sys.argv");
912914
}
913915
return _PyStatus_OK();
914916
}
915917

916-
/* Update interpreter state based on supplied configuration settings
917-
*
918-
* After calling this function, most of the restrictions on the interpreter
919-
* are lifted. The only remaining incomplete settings are those related
920-
* to the main module (sys.argv[0], __main__ metadata)
921-
*
922-
* Calling this when the interpreter is not initializing, is already
923-
* initialized or without a valid current thread state is a fatal error.
924-
* Other errors should be reported as normal Python exceptions with a
925-
* non-zero return code.
926-
*/
918+
927919
static PyStatus
928-
pyinit_main(PyThreadState *tstate)
920+
init_interp_main(PyThreadState *tstate)
929921
{
930-
_PyRuntimeState *runtime = tstate->interp->runtime;
931-
if (!runtime->core_initialized) {
932-
return _PyStatus_ERR("runtime core not initialized");
933-
}
934-
935-
/* Configure the main interpreter */
922+
PyStatus status;
923+
int is_main_interp = _Py_IsMainInterpreter(tstate);
936924
PyInterpreterState *interp = tstate->interp;
937925
PyConfig *config = &interp->config;
938926

939-
if (runtime->initialized) {
940-
return _Py_ReconfigureMainInterpreter(interp);
941-
}
942-
943927
if (!config->_install_importlib) {
944928
/* Special mode for freeze_importlib: run with no import system
945929
*
946930
* This means anything which needs support from extension modules
947931
* or pure Python code in the standard library won't work.
948932
*/
949-
runtime->initialized = 1;
933+
if (is_main_interp) {
934+
interp->runtime->initialized = 1;
935+
}
950936
return _PyStatus_OK();
951937
}
952938

953-
if (_PyTime_Init() < 0) {
954-
return _PyStatus_ERR("can't initialize time");
955-
}
939+
if (is_main_interp) {
940+
if (_PyTime_Init() < 0) {
941+
return _PyStatus_ERR("can't initialize time");
942+
}
956943

957-
if (_PySys_InitMain(tstate) < 0) {
958-
return _PyStatus_ERR("can't finish initializing sys");
944+
if (_PySys_InitMain(tstate) < 0) {
945+
return _PyStatus_ERR("can't finish initializing sys");
946+
}
959947
}
960948

961-
PyStatus status = init_importlib_external(tstate);
949+
status = init_importlib_external(tstate);
962950
if (_PyStatus_EXCEPTION(status)) {
963951
return status;
964952
}
965953

966-
/* initialize the faulthandler module */
967-
status = _PyFaulthandler_Init(config->faulthandler);
968-
if (_PyStatus_EXCEPTION(status)) {
969-
return status;
954+
if (is_main_interp) {
955+
/* initialize the faulthandler module */
956+
status = _PyFaulthandler_Init(config->faulthandler);
957+
if (_PyStatus_EXCEPTION(status)) {
958+
return status;
959+
}
970960
}
971961

972962
status = _PyUnicode_InitEncodings(tstate);
973963
if (_PyStatus_EXCEPTION(status)) {
974964
return status;
975965
}
976966

977-
if (config->install_signal_handlers) {
978-
status = init_signals(tstate);
979-
if (_PyStatus_EXCEPTION(status)) {
980-
return status;
967+
if (is_main_interp) {
968+
if (config->install_signal_handlers) {
969+
status = init_signals(tstate);
970+
if (_PyStatus_EXCEPTION(status)) {
971+
return status;
972+
}
981973
}
982-
}
983974

984-
if (_PyTraceMalloc_Init(config->tracemalloc) < 0) {
985-
return _PyStatus_ERR("can't initialize tracemalloc");
975+
if (_PyTraceMalloc_Init(config->tracemalloc) < 0) {
976+
return _PyStatus_ERR("can't initialize tracemalloc");
977+
}
986978
}
987979

988-
status = add_main_module(interp);
980+
status = init_sys_streams(tstate);
989981
if (_PyStatus_EXCEPTION(status)) {
990982
return status;
991983
}
992984

993-
status = init_sys_streams(tstate);
985+
status = init_set_builtins_open(tstate);
994986
if (_PyStatus_EXCEPTION(status)) {
995987
return status;
996988
}
997989

998-
status = init_set_builtins_open(tstate);
990+
status = add_main_module(interp);
999991
if (_PyStatus_EXCEPTION(status)) {
1000992
return status;
1001993
}
1002994

1003-
/* Initialize warnings. */
1004-
PyObject *warnoptions = PySys_GetObject("warnoptions");
1005-
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
1006-
{
1007-
PyObject *warnings_module = PyImport_ImportModule("warnings");
1008-
if (warnings_module == NULL) {
1009-
fprintf(stderr, "'import warnings' failed; traceback:\n");
1010-
_PyErr_Print(tstate);
995+
if (is_main_interp) {
996+
/* Initialize warnings. */
997+
PyObject *warnoptions = PySys_GetObject("warnoptions");
998+
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
999+
{
1000+
PyObject *warnings_module = PyImport_ImportModule("warnings");
1001+
if (warnings_module == NULL) {
1002+
fprintf(stderr, "'import warnings' failed; traceback:\n");
1003+
_PyErr_Print(tstate);
1004+
}
1005+
Py_XDECREF(warnings_module);
10111006
}
1012-
Py_XDECREF(warnings_module);
1013-
}
10141007

1015-
runtime->initialized = 1;
1008+
interp->runtime->initialized = 1;
1009+
}
10161010

10171011
if (config->site_import) {
10181012
status = init_import_site();
@@ -1021,14 +1015,47 @@ pyinit_main(PyThreadState *tstate)
10211015
}
10221016
}
10231017

1018+
if (is_main_interp) {
10241019
#ifndef MS_WINDOWS
1025-
emit_stderr_warning_for_legacy_locale(runtime);
1020+
emit_stderr_warning_for_legacy_locale(interp->runtime);
10261021
#endif
1022+
}
10271023

10281024
return _PyStatus_OK();
10291025
}
10301026

10311027

1028+
/* Update interpreter state based on supplied configuration settings
1029+
*
1030+
* After calling this function, most of the restrictions on the interpreter
1031+
* are lifted. The only remaining incomplete settings are those related
1032+
* to the main module (sys.argv[0], __main__ metadata)
1033+
*
1034+
* Calling this when the interpreter is not initializing, is already
1035+
* initialized or without a valid current thread state is a fatal error.
1036+
* Other errors should be reported as normal Python exceptions with a
1037+
* non-zero return code.
1038+
*/
1039+
static PyStatus
1040+
pyinit_main(PyThreadState *tstate)
1041+
{
1042+
PyInterpreterState *interp = tstate->interp;
1043+
if (!interp->runtime->core_initialized) {
1044+
return _PyStatus_ERR("runtime core not initialized");
1045+
}
1046+
1047+
if (interp->runtime->initialized) {
1048+
return _Py_ReconfigureMainInterpreter(tstate);
1049+
}
1050+
1051+
PyStatus status = init_interp_main(tstate);
1052+
if (_PyStatus_EXCEPTION(status)) {
1053+
return status;
1054+
}
1055+
return _PyStatus_OK();
1056+
}
1057+
1058+
10321059
PyStatus
10331060
_Py_InitializeMain(void)
10341061
{
@@ -1440,6 +1467,7 @@ Py_Finalize(void)
14401467
Py_FinalizeEx();
14411468
}
14421469

1470+
14431471
/* Create and initialize a new interpreter and thread, and return the
14441472
new thread. This requires that Py_Initialize() has been called
14451473
first.
@@ -1499,7 +1527,7 @@ new_interpreter(PyThreadState **tstate_p)
14991527

15001528
status = _PyConfig_Copy(&interp->config, config);
15011529
if (_PyStatus_EXCEPTION(status)) {
1502-
return status;
1530+
goto done;
15031531
}
15041532
config = &interp->config;
15051533

@@ -1508,109 +1536,87 @@ new_interpreter(PyThreadState **tstate_p)
15081536
/* XXX The following is lax in error checking */
15091537
PyObject *modules = PyDict_New();
15101538
if (modules == NULL) {
1511-
return _PyStatus_ERR("can't make modules dictionary");
1539+
status = _PyStatus_ERR("can't make modules dictionary");
1540+
goto done;
15121541
}
15131542
interp->modules = modules;
15141543

15151544
PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys");
15161545
if (sysmod != NULL) {
15171546
interp->sysdict = PyModule_GetDict(sysmod);
15181547
if (interp->sysdict == NULL) {
1519-
goto handle_error;
1548+
goto handle_exc;
15201549
}
15211550
Py_INCREF(interp->sysdict);
15221551
PyDict_SetItemString(interp->sysdict, "modules", modules);
15231552
if (_PySys_InitMain(tstate) < 0) {
1524-
return _PyStatus_ERR("can't finish initializing sys");
1553+
status = _PyStatus_ERR("can't finish initializing sys");
1554+
goto done;
15251555
}
15261556
}
15271557
else if (_PyErr_Occurred(tstate)) {
1528-
goto handle_error;
1558+
goto handle_exc;
15291559
}
15301560

15311561
PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins");
15321562
if (bimod != NULL) {
15331563
interp->builtins = PyModule_GetDict(bimod);
15341564
if (interp->builtins == NULL)
1535-
goto handle_error;
1565+
goto handle_exc;
15361566
Py_INCREF(interp->builtins);
15371567
}
15381568
else if (_PyErr_Occurred(tstate)) {
1539-
goto handle_error;
1569+
goto handle_exc;
15401570
}
15411571

15421572
if (bimod != NULL && sysmod != NULL) {
15431573
status = _PyBuiltins_AddExceptions(bimod);
15441574
if (_PyStatus_EXCEPTION(status)) {
1545-
return status;
1575+
goto done;
15461576
}
15471577

15481578
status = _PySys_SetPreliminaryStderr(interp->sysdict);
15491579
if (_PyStatus_EXCEPTION(status)) {
1550-
return status;
1580+
goto done;
15511581
}
15521582

15531583
status = _PyImportHooks_Init(tstate);
15541584
if (_PyStatus_EXCEPTION(status)) {
1555-
return status;
1585+
goto done;
15561586
}
15571587

15581588
status = init_importlib(tstate, sysmod);
15591589
if (_PyStatus_EXCEPTION(status)) {
1560-
return status;
1590+
goto done;
15611591
}
15621592

1563-
status = init_importlib_external(tstate);
1593+
status = init_interp_main(tstate);
15641594
if (_PyStatus_EXCEPTION(status)) {
1565-
return status;
1566-
}
1567-
1568-
status = _PyUnicode_InitEncodings(tstate);
1569-
if (_PyStatus_EXCEPTION(status)) {
1570-
return status;
1571-
}
1572-
1573-
status = init_sys_streams(tstate);
1574-
if (_PyStatus_EXCEPTION(status)) {
1575-
return status;
1576-
}
1577-
1578-
status = init_set_builtins_open(tstate);
1579-
if (_PyStatus_EXCEPTION(status)) {
1580-
return status;
1581-
}
1582-
1583-
status = add_main_module(interp);
1584-
if (_PyStatus_EXCEPTION(status)) {
1585-
return status;
1586-
}
1587-
1588-
if (config->site_import) {
1589-
status = init_import_site();
1590-
if (_PyStatus_EXCEPTION(status)) {
1591-
return status;
1592-
}
1595+
goto done;
15931596
}
15941597
}
15951598

15961599
if (_PyErr_Occurred(tstate)) {
1597-
goto handle_error;
1600+
goto handle_exc;
15981601
}
15991602

16001603
*tstate_p = tstate;
16011604
return _PyStatus_OK();
16021605

1603-
handle_error:
1604-
/* Oops, it didn't work. Undo it all. */
1606+
handle_exc:
1607+
status = _PyStatus_OK();
16051608

1609+
done:
1610+
*tstate_p = NULL;
1611+
1612+
/* Oops, it didn't work. Undo it all. */
16061613
PyErr_PrintEx(0);
16071614
PyThreadState_Clear(tstate);
16081615
PyThreadState_Delete(tstate);
16091616
PyInterpreterState_Delete(interp);
16101617
PyThreadState_Swap(save_tstate);
16111618

1612-
*tstate_p = NULL;
1613-
return _PyStatus_OK();
1619+
return status;
16141620
}
16151621

16161622
PyThreadState *

0 commit comments

Comments
 (0)