Commit 484f20d2 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-36444: Add _PyCoreConfig._init_main (GH-12572)

* Add _PyCoreConfig._init_main: if equals to zero,
  _Py_InitializeFromConfig() doesn't call
  _Py_InitializeMainInterpreter().
* Add interp_p parameter to _Py_InitializeFromConfig().
* pymain_init() now calls _Py_InitializeFromConfig().
* Make _Py_InitializeCore() private.
parent 8b9dbc01
...@@ -365,6 +365,9 @@ typedef struct { ...@@ -365,6 +365,9 @@ typedef struct {
If set to -1 (default), inherit Py_FrozenFlag value. */ If set to -1 (default), inherit Py_FrozenFlag value. */
int _frozen; int _frozen;
/* If non-zero, use "main" Python initialization */
int _init_main;
} _PyCoreConfig; } _PyCoreConfig;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
...@@ -398,7 +401,8 @@ typedef struct { ...@@ -398,7 +401,8 @@ typedef struct {
.buffered_stdio = -1, \ .buffered_stdio = -1, \
._install_importlib = 1, \ ._install_importlib = 1, \
._check_hash_pycs_mode = "default", \ ._check_hash_pycs_mode = "default", \
._frozen = -1} ._frozen = -1, \
._init_main = 1}
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ /* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
......
...@@ -20,9 +20,6 @@ PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig( ...@@ -20,9 +20,6 @@ PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig(
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig( PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig(
const _PyCoreConfig *coreconfig); const _PyCoreConfig *coreconfig);
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
const _PyCoreConfig *config,
PyInterpreterState **interp);
PyAPI_FUNC(int) _Py_IsCoreInitialized(void); PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
...@@ -32,7 +29,8 @@ PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter( ...@@ -32,7 +29,8 @@ PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
/* Initialization and finalization */ /* Initialization and finalization */
PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig( PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
const _PyCoreConfig *config); const _PyCoreConfig *config,
PyInterpreterState **interp_p);
PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err); PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err);
/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
......
...@@ -338,6 +338,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ...@@ -338,6 +338,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'_install_importlib': 1, '_install_importlib': 1,
'_check_hash_pycs_mode': 'default', '_check_hash_pycs_mode': 'default',
'_frozen': 0, '_frozen': 0,
'_init_main': 1,
} }
if MS_WINDOWS: if MS_WINDOWS:
DEFAULT_PRE_CONFIG.update({ DEFAULT_PRE_CONFIG.update({
......
...@@ -53,19 +53,6 @@ done: ...@@ -53,19 +53,6 @@ done:
} }
static _PyInitError
pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args,
PyInterpreterState **interp_p)
{
_PyInitError err = _PyCoreConfig_Read(config, args);
if (_Py_INIT_FAILED(err)) {
return err;
}
return _Py_InitializeCore(config, interp_p);
}
static _PyInitError static _PyInitError
pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
{ {
...@@ -91,18 +78,22 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) ...@@ -91,18 +78,22 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
} }
_PyCoreConfig config = _PyCoreConfig_INIT; _PyCoreConfig config = _PyCoreConfig_INIT;
err = pymain_init_coreconfig(&config, args, interp_p);
_PyCoreConfig_Clear(&config); err = _PyCoreConfig_Read(&config, args);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; goto done;
} }
err = _Py_InitializeMainInterpreter(*interp_p); err = _Py_InitializeFromConfig(&config, interp_p);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; goto done;
} }
return _Py_INIT_OK(); err = _Py_INIT_OK();
done:
_PyCoreConfig_Clear(&config);
return err;
} }
......
...@@ -84,8 +84,9 @@ main(int argc, char *argv[]) ...@@ -84,8 +84,9 @@ main(int argc, char *argv[])
/* Don't install importlib, since it could execute outdated bytecode. */ /* Don't install importlib, since it could execute outdated bytecode. */
config._install_importlib = 0; config._install_importlib = 0;
config._frozen = 1; config._frozen = 1;
config._init_main = 0;
_PyInitError err = _Py_InitializeFromConfig(&config); _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any /* No need to call _PyCoreConfig_Clear() since we didn't allocate any
memory: program_name is a constant string. */ memory: program_name is a constant string. */
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
......
...@@ -529,7 +529,7 @@ static int test_init_from_config(void) ...@@ -529,7 +529,7 @@ static int test_init_from_config(void)
Py_FrozenFlag = 0; Py_FrozenFlag = 0;
config._frozen = 1; config._frozen = 1;
err = _Py_InitializeFromConfig(&config); err = _Py_InitializeFromConfig(&config, NULL);
/* Don't call _PyCoreConfig_Clear() since all strings are static */ /* Don't call _PyCoreConfig_Clear() since all strings are static */
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
...@@ -638,7 +638,7 @@ static int test_init_isolated(void) ...@@ -638,7 +638,7 @@ static int test_init_isolated(void)
config.program_name = L"./_testembed"; config.program_name = L"./_testembed";
test_init_env_dev_mode_putenvs(); test_init_env_dev_mode_putenvs();
err = _Py_InitializeFromConfig(&config); err = _Py_InitializeFromConfig(&config, NULL);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
} }
...@@ -669,7 +669,7 @@ static int test_preinit_isolated1(void) ...@@ -669,7 +669,7 @@ static int test_preinit_isolated1(void)
config.program_name = L"./_testembed"; config.program_name = L"./_testembed";
test_init_env_dev_mode_putenvs(); test_init_env_dev_mode_putenvs();
err = _Py_InitializeFromConfig(&config); err = _Py_InitializeFromConfig(&config, NULL);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
} }
...@@ -706,7 +706,7 @@ static int test_preinit_isolated2(void) ...@@ -706,7 +706,7 @@ static int test_preinit_isolated2(void)
config.program_name = L"./_testembed"; config.program_name = L"./_testembed";
test_init_env_dev_mode_putenvs(); test_init_env_dev_mode_putenvs();
err = _Py_InitializeFromConfig(&config); err = _Py_InitializeFromConfig(&config, NULL);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
} }
...@@ -723,7 +723,7 @@ static int test_init_dev_mode(void) ...@@ -723,7 +723,7 @@ static int test_init_dev_mode(void)
putenv("PYTHONMALLOC="); putenv("PYTHONMALLOC=");
config.dev_mode = 1; config.dev_mode = 1;
config.program_name = L"./_testembed"; config.program_name = L"./_testembed";
_PyInitError err = _Py_InitializeFromConfig(&config); _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
} }
......
...@@ -610,6 +610,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) ...@@ -610,6 +610,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
COPY_WSTR_ATTR(run_filename); COPY_WSTR_ATTR(run_filename);
COPY_ATTR(_check_hash_pycs_mode); COPY_ATTR(_check_hash_pycs_mode);
COPY_ATTR(_frozen); COPY_ATTR(_frozen);
COPY_ATTR(_init_main);
#undef COPY_ATTR #undef COPY_ATTR
#undef COPY_STR_ATTR #undef COPY_STR_ATTR
...@@ -715,6 +716,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) ...@@ -715,6 +716,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
SET_ITEM_INT(_install_importlib); SET_ITEM_INT(_install_importlib);
SET_ITEM_STR(_check_hash_pycs_mode); SET_ITEM_STR(_check_hash_pycs_mode);
SET_ITEM_INT(_frozen); SET_ITEM_INT(_frozen);
SET_ITEM_INT(_init_main);
return dict; return dict;
......
...@@ -82,7 +82,7 @@ Py_FrozenMain(int argc, char **argv) ...@@ -82,7 +82,7 @@ Py_FrozenMain(int argc, char **argv)
if (argc >= 1) if (argc >= 1)
Py_SetProgramName(argv_copy[0]); Py_SetProgramName(argv_copy[0]);
err = _Py_InitializeFromConfig(&config); err = _Py_InitializeFromConfig(&config, NULL);
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any /* No need to call _PyCoreConfig_Clear() since we didn't allocate any
memory: program_name is a constant string. */ memory: program_name is a constant string. */
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
......
...@@ -458,7 +458,7 @@ _Py_SetLocaleFromEnv(int category) ...@@ -458,7 +458,7 @@ _Py_SetLocaleFromEnv(int category)
/* Global initializations. Can be undone by Py_Finalize(). Don't /* Global initializations. Can be undone by Py_Finalize(). Don't
call this twice without an intervening Py_Finalize() call. call this twice without an intervening Py_Finalize() call.
Every call to _Py_InitializeCore, Py_Initialize or Py_InitializeEx Every call to _Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
must have a corresponding call to Py_Finalize. must have a corresponding call to Py_Finalize.
Locking: you must hold the interpreter lock while calling these APIs. Locking: you must hold the interpreter lock while calling these APIs.
...@@ -832,7 +832,7 @@ pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config, ...@@ -832,7 +832,7 @@ pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
* to the Python C API (unless the API is explicitly listed as being * to the Python C API (unless the API is explicitly listed as being
* safe to call without calling Py_Initialize first) * safe to call without calling Py_Initialize first)
*/ */
_PyInitError static _PyInitError
_Py_InitializeCore(const _PyCoreConfig *src_config, _Py_InitializeCore(const _PyCoreConfig *src_config,
PyInterpreterState **interp_p) PyInterpreterState **interp_p)
{ {
...@@ -981,7 +981,8 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp) ...@@ -981,7 +981,8 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
#undef _INIT_DEBUG_PRINT #undef _INIT_DEBUG_PRINT
_PyInitError _PyInitError
_Py_InitializeFromConfig(const _PyCoreConfig *config) _Py_InitializeFromConfig(const _PyCoreConfig *config,
PyInterpreterState **interp_p)
{ {
PyInterpreterState *interp = NULL; PyInterpreterState *interp = NULL;
_PyInitError err; _PyInitError err;
...@@ -989,12 +990,18 @@ _Py_InitializeFromConfig(const _PyCoreConfig *config) ...@@ -989,12 +990,18 @@ _Py_InitializeFromConfig(const _PyCoreConfig *config)
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
if (interp_p) {
*interp_p = interp;
}
config = &interp->core_config; config = &interp->core_config;
if (config->_init_main) {
err = _Py_InitializeMainInterpreter(interp); err = _Py_InitializeMainInterpreter(interp);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
}
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -1007,13 +1014,10 @@ Py_InitializeEx(int install_sigs) ...@@ -1007,13 +1014,10 @@ Py_InitializeEx(int install_sigs)
return; return;
} }
_PyInitError err;
_PyCoreConfig config = _PyCoreConfig_INIT; _PyCoreConfig config = _PyCoreConfig_INIT;
config.install_signal_handlers = install_sigs; config.install_signal_handlers = install_sigs;
err = _Py_InitializeFromConfig(&config); _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
_PyCoreConfig_Clear(&config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err); _Py_ExitInitError(err);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment