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

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) */

277279278280

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;

902904903905

PyObject *argv = _PyWideStringList_AsList(&config->argv);

904906

if (argv == NULL) {

905907

return _PyStatus_NO_MEMORY(); \

906908

}

907909908-

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

}

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+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;

938926939-

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

}

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);

962950

if (_PyStatus_EXCEPTION(status)) {

963951

return 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

}

971961972962

status = _PyUnicode_InitEncodings(tstate);

973963

if (_PyStatus_EXCEPTION(status)) {

974964

return 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);

989981

if (_PyStatus_EXCEPTION(status)) {

990982

return status;

991983

}

992984993-

status = init_sys_streams(tstate);

985+

status = init_set_builtins_open(tstate);

994986

if (_PyStatus_EXCEPTION(status)) {

995987

return status;

996988

}

997989998-

status = init_set_builtins_open(tstate);

990+

status = add_main_module(interp);

999991

if (_PyStatus_EXCEPTION(status)) {

1000992

return 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+

}

1016101010171011

if (config->site_import) {

10181012

status = 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+

}

1027102310281024

return _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+10321059

PyStatus

10331060

_Py_InitializeMain(void)

10341061

{

@@ -1440,6 +1467,7 @@ Py_Finalize(void)

14401467

Py_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)

1499152715001528

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;

1514154315151544

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

}

1530156015311561

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

}

1541157115421572

if (bimod != NULL && sysmod != NULL) {

15431573

status = _PyBuiltins_AddExceptions(bimod);

15441574

if (_PyStatus_EXCEPTION(status)) {

1545-

return status;

1575+

goto done;

15461576

}

1547157715481578

status = _PySys_SetPreliminaryStderr(interp->sysdict);

15491579

if (_PyStatus_EXCEPTION(status)) {

1550-

return status;

1580+

goto done;

15511581

}

1552158215531583

status = _PyImportHooks_Init(tstate);

15541584

if (_PyStatus_EXCEPTION(status)) {

1555-

return status;

1585+

goto done;

15561586

}

1557158715581588

status = init_importlib(tstate, sysmod);

15591589

if (_PyStatus_EXCEPTION(status)) {

1560-

return status;

1590+

goto done;

15611591

}

156215921563-

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

}

1595159815961599

if (_PyErr_Occurred(tstate)) {

1597-

goto handle_error;

1600+

goto handle_exc;

15981601

}

1599160216001603

*tstate_p = tstate;

16011604

return _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. */

16061613

PyErr_PrintEx(0);

16071614

PyThreadState_Clear(tstate);

16081615

PyThreadState_Delete(tstate);

16091616

PyInterpreterState_Delete(interp);

16101617

PyThreadState_Swap(save_tstate);

161116181612-

*tstate_p = NULL;

1613-

return _PyStatus_OK();

1619+

return status;

16141620

}

1615162116161622

PyThreadState *