diff options
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 80 |
1 files changed, 67 insertions, 13 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d106c45be7..fd04b8233b 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -69,6 +69,7 @@ extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Init(void); extern int _PyTraceMalloc_Fini(void); +extern void _Py_ReadyTypes(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -112,6 +113,7 @@ PyModule_GetWarningsModule(void) return PyImport_ImportModule("warnings"); } + /* APIs to access the initialization flags * * Can be called prior to Py_Initialize. @@ -366,8 +368,8 @@ void _Py_InitializeCore(const _PyCoreConfig *config) PyThreadState *tstate; PyObject *bimod, *sysmod, *pstderr; char *p; - extern void _Py_ReadyTypes(void); _PyCoreConfig core_config = _PyCoreConfig_INIT; + _PyMainInterpreterConfig preinit_config = _PyMainInterpreterConfig_INIT; if (config != NULL) { core_config = *config; @@ -428,6 +430,7 @@ void _Py_InitializeCore(const _PyCoreConfig *config) if (interp == NULL) Py_FatalError("Py_InitializeCore: can't make main interpreter"); interp->core_config = core_config; + interp->config = preinit_config; tstate = PyThreadState_New(interp); if (tstate == NULL) @@ -518,21 +521,62 @@ void _Py_InitializeCore(const _PyCoreConfig *config) _Py_CoreInitialized = 1; } -int -_Py_InitializeMainInterpreter(int install_sigs) +/* Read configuration settings from standard locations + * + * This function doesn't make any changes to the interpreter state - it + * merely populates any missing configuration settings. This allows an + * embedding application to completely override a config option by + * setting it before calling this function, or else modify the default + * setting before passing the fully populated config to Py_EndInitialization. + * + * More advanced selective initialization tricks are possible by calling + * this function multiple times with various preconfigured settings. + */ + +int _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *config) +{ + /* Signal handlers are installed by default */ + if (config->install_signal_handlers < 0) { + config->install_signal_handlers = 1; + } + + return 0; +} + +/* Update interpreter state based on supplied configuration settings + * + * After calling this function, most of the restrictions on the interpreter + * are lifted. The only remaining incomplete settings are those related + * to the main module (sys.argv[0], __main__ metadata) + * + * Calling this when the interpreter is not initializing, is already + * initialized or without a valid current thread state is a fatal error. + * Other errors should be reported as normal Python exceptions with a + * non-zero return code. + */ +int _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) { PyInterpreterState *interp; PyThreadState *tstate; + if (!_Py_CoreInitialized) { + Py_FatalError("Py_InitializeMainInterpreter: runtime core not initialized"); + } + if (_Py_Initialized) { + Py_FatalError("Py_InitializeMainInterpreter: main interpreter already initialized"); + } + /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); if (!tstate) - Py_FatalError("Py_Initialize: failed to read thread state"); + Py_FatalError("Py_InitializeMainInterpreter: failed to read thread state"); interp = tstate->interp; if (!interp) - Py_FatalError("Py_Initialize: failed to get interpreter"); + Py_FatalError("Py_InitializeMainInterpreter: failed to get interpreter"); /* Now finish configuring the main interpreter */ + interp->config = *config; + if (interp->core_config._disable_importlib) { /* Special mode for freeze_importlib: run with no import system * @@ -545,7 +589,7 @@ _Py_InitializeMainInterpreter(int install_sigs) /* TODO: Report exceptions rather than fatal errors below here */ if (_PyTime_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize time"); + Py_FatalError("Py_InitializeMainInterpreter: can't initialize time"); /* Finish setting up the sys module and import system */ /* GetPath may initialize state that _PySys_EndInit locks @@ -559,21 +603,21 @@ _Py_InitializeMainInterpreter(int install_sigs) /* initialize the faulthandler module */ if (_PyFaulthandler_Init()) - Py_FatalError("Py_Initialize: can't initialize faulthandler"); + Py_FatalError("Py_InitializeMainInterpreter: can't initialize faulthandler"); if (initfsencoding(interp) < 0) - Py_FatalError("Py_Initialize: unable to load the file system codec"); + Py_FatalError("Py_InitializeMainInterpreter: unable to load the file system codec"); - if (install_sigs) + if (config->install_signal_handlers) initsigs(); /* Signal handling stuff, including initintr() */ if (_PyTraceMalloc_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize tracemalloc"); + Py_FatalError("Py_InitializeMainInterpreter: can't initialize tracemalloc"); initmain(interp); /* Module __main__ */ if (initstdio() < 0) Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); + "Py_InitializeMainInterpreter: can't initialize sys standard streams"); /* Initialize warnings. */ if (PySys_HasWarnOptions()) { @@ -590,19 +634,27 @@ _Py_InitializeMainInterpreter(int install_sigs) if (!Py_NoSiteFlag) initsite(); /* Module site */ - return 0; + return 0; } +#undef _INIT_DEBUG_PRINT + void _Py_InitializeEx_Private(int install_sigs, int install_importlib) { _PyCoreConfig core_config = _PyCoreConfig_INIT; + _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT; /* TODO: Moar config options! */ core_config.ignore_environment = Py_IgnoreEnvironmentFlag; core_config._disable_importlib = !install_importlib; + config.install_signal_handlers = install_sigs; _Py_InitializeCore(&core_config); - _Py_InitializeMainInterpreter(install_sigs); + /* TODO: Print any exceptions raised by these operations */ + if (_Py_ReadMainInterpreterConfig(&config)) + Py_FatalError("Py_Initialize: Py_ReadMainInterpreterConfig failed"); + if (_Py_InitializeMainInterpreter(&config)) + Py_FatalError("Py_Initialize: Py_InitializeMainInterpreter failed"); } @@ -932,10 +984,12 @@ Py_NewInterpreter(void) /* Copy the current interpreter config into the new interpreter */ if (save_tstate != NULL) { interp->core_config = save_tstate->interp->core_config; + interp->config = save_tstate->interp->config; } else { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = PyInterpreterState_Main(); interp->core_config = main_interp->core_config; + interp->config = main_interp->config; } /* XXX The following is lax in error checking */ |