bpo-38858: Add init_interp_main() subfunction (GH-17347) · python/cpython@b005136
@@ -260,6 +260,7 @@ _Py_LegacyLocaleDetected(int warn)
260260#endif
261261}
262262263+#ifndef MS_WINDOWS
263264static 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)
274275PySys_FormatStderr("%s", _C_LOCALE_WARNING);
275276 }
276277}
278+#endif /* !defined(MS_WINDOWS) */
277279278280typedef struct _CandidateLocale {
279281const 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(). */
898900static PyStatus
899-_Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
901+_Py_ReconfigureMainInterpreter(PyThreadState *tstate)
900902{
901-PyConfig *config = &interp->config;
903+PyConfig *config = &tstate->interp->config;
902904903905PyObject *argv = _PyWideStringList_AsList(&config->argv);
904906if (argv == NULL) {
905907return _PyStatus_NO_MEMORY(); \
906908 }
907909908-int res = PyDict_SetItemString(interp->sysdict, "argv", argv);
910+int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv);
909911Py_DECREF(argv);
910912if (res < 0) {
911913return _PyStatus_ERR("fail to set sys.argv");
912914 }
913915return _PyStatus_OK();
914916}
915917916-/* 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+927919static 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);
936924PyInterpreterState *interp = tstate->interp;
937925PyConfig *config = &interp->config;
938926939-if (runtime->initialized) {
940-return _Py_ReconfigureMainInterpreter(interp);
941- }
942-943927if (!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+ }
950936return _PyStatus_OK();
951937 }
952938953-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+ }
956943957-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 }
960948961-PyStatus status = init_importlib_external(tstate);
949+status = init_importlib_external(tstate);
962950if (_PyStatus_EXCEPTION(status)) {
963951return status;
964952 }
965953966-/* 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 }
971961972962status = _PyUnicode_InitEncodings(tstate);
973963if (_PyStatus_EXCEPTION(status)) {
974964return status;
975965 }
976966977-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- }
983974984-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 }
987979988-status = add_main_module(interp);
980+status = init_sys_streams(tstate);
989981if (_PyStatus_EXCEPTION(status)) {
990982return status;
991983 }
992984993-status = init_sys_streams(tstate);
985+status = init_set_builtins_open(tstate);
994986if (_PyStatus_EXCEPTION(status)) {
995987return status;
996988 }
997989998-status = init_set_builtins_open(tstate);
990+status = add_main_module(interp);
999991if (_PyStatus_EXCEPTION(status)) {
1000992return status;
1001993 }
10029941003-/* 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- }
101410071015-runtime->initialized = 1;
1008+interp->runtime->initialized = 1;
1009+ }
1016101010171011if (config->site_import) {
10181012status = init_import_site();
@@ -1021,14 +1015,47 @@ pyinit_main(PyThreadState *tstate)
10211015 }
10221016 }
102310171018+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+ }
1027102310281024return _PyStatus_OK();
10291025}
10301026103110271028+/* 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+10321059PyStatus
10331060_Py_InitializeMain(void)
10341061{
@@ -1440,6 +1467,7 @@ Py_Finalize(void)
14401467Py_FinalizeEx();
14411468}
144214691470+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)
1499152715001528status = _PyConfig_Copy(&interp->config, config);
15011529if (_PyStatus_EXCEPTION(status)) {
1502-return status;
1530+goto done;
15031531 }
15041532config = &interp->config;
15051533@@ -1508,109 +1536,87 @@ new_interpreter(PyThreadState **tstate_p)
15081536/* XXX The following is lax in error checking */
15091537PyObject *modules = PyDict_New();
15101538if (modules == NULL) {
1511-return _PyStatus_ERR("can't make modules dictionary");
1539+status = _PyStatus_ERR("can't make modules dictionary");
1540+ goto done;
15121541 }
15131542interp->modules = modules;
1514154315151544PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys");
15161545if (sysmod != NULL) {
15171546interp->sysdict = PyModule_GetDict(sysmod);
15181547if (interp->sysdict == NULL) {
1519- goto handle_error;
1548+ goto handle_exc;
15201549 }
15211550Py_INCREF(interp->sysdict);
15221551PyDict_SetItemString(interp->sysdict, "modules", modules);
15231552if (_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 }
15271557else if (_PyErr_Occurred(tstate)) {
1528- goto handle_error;
1558+ goto handle_exc;
15291559 }
1530156015311561PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins");
15321562if (bimod != NULL) {
15331563interp->builtins = PyModule_GetDict(bimod);
15341564if (interp->builtins == NULL)
1535- goto handle_error;
1565+ goto handle_exc;
15361566Py_INCREF(interp->builtins);
15371567 }
15381568else if (_PyErr_Occurred(tstate)) {
1539- goto handle_error;
1569+ goto handle_exc;
15401570 }
1541157115421572if (bimod != NULL && sysmod != NULL) {
15431573status = _PyBuiltins_AddExceptions(bimod);
15441574if (_PyStatus_EXCEPTION(status)) {
1545-return status;
1575+goto done;
15461576 }
1547157715481578status = _PySys_SetPreliminaryStderr(interp->sysdict);
15491579if (_PyStatus_EXCEPTION(status)) {
1550-return status;
1580+goto done;
15511581 }
1552158215531583status = _PyImportHooks_Init(tstate);
15541584if (_PyStatus_EXCEPTION(status)) {
1555-return status;
1585+goto done;
15561586 }
1557158715581588status = init_importlib(tstate, sysmod);
15591589if (_PyStatus_EXCEPTION(status)) {
1560-return status;
1590+goto done;
15611591 }
156215921563-status = init_importlib_external(tstate);
1593+status = init_interp_main(tstate);
15641594if (_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 }
1595159815961599if (_PyErr_Occurred(tstate)) {
1597- goto handle_error;
1600+ goto handle_exc;
15981601 }
1599160216001603*tstate_p = tstate;
16011604return _PyStatus_OK();
160216051603-handle_error:
1604-/* Oops, it didn't work. Undo it all. */
1606+handle_exc:
1607+status = _PyStatus_OK();
160516081609+done:
1610+*tstate_p = NULL;
1611+1612+/* Oops, it didn't work. Undo it all. */
16061613PyErr_PrintEx(0);
16071614PyThreadState_Clear(tstate);
16081615PyThreadState_Delete(tstate);
16091616PyInterpreterState_Delete(interp);
16101617PyThreadState_Swap(save_tstate);
161116181612-*tstate_p = NULL;
1613-return _PyStatus_OK();
1619+return status;
16141620}
1615162116161622PyThreadState *