From a6fbc4e25e1dc7d1c9a26888b9115bc6c2afc101 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 25 Mar 2019 18:37:10 +0100 Subject: bpo-36301: Add _Py_PreInitializeFromConfig() (GH-12536) * Initialize _PyPreConfig.dev_mode to -1. * _PyPreConfig_Read(): coreconfig has the priority over preconfig. * _PyCoreConfig_Read() now calls _PyPreCmdline_Read() internally. * config_from_cmdline() now pass _PyPreCmdline to config_read(). * Add _PyPreCmdline_Copy(). --- Include/cpython/coreconfig.h | 4 ++- Include/cpython/pylifecycle.h | 2 ++ Include/internal/pycore_coreconfig.h | 14 +++++++- Python/coreconfig.c | 62 +++++++++++++++++++++++++++++++----- Python/preconfig.c | 62 ++++++++++++++++++++++++++++++++++-- Python/pylifecycle.c | 35 +++++++++++++------- 6 files changed, 155 insertions(+), 24 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index 8362209..bb086cb 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -115,7 +115,9 @@ typedef struct { .isolated = -1, \ .use_environment = -1, \ .coerce_c_locale = -1, \ - .utf8_mode = -1} + .utf8_mode = -1, \ + .dev_mode = -1, \ + .allocator = NULL} /* --- _PyCoreConfig ---------------------------------------------- */ diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 1caeb98..a226de8 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -17,6 +17,8 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void); PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig( _PyPreConfig *preconfig); +PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig( + const _PyCoreConfig *coreconfig); PyAPI_FUNC(_PyInitError) _Py_InitializeCore( PyInterpreterState **interp, diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index 949bc9b..d44172e 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -25,11 +25,22 @@ typedef struct { /* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline); +PyAPI_FUNC(int) _PyPreCmdline_Copy(_PyPreCmdline *cmdline, + const _PyPreCmdline *cmdline2); PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args); +PyAPI_FUNC(void) _PyPreCmdline_GetPreConfig( + _PyPreCmdline *cmdline, + const _PyPreConfig *config); PyAPI_FUNC(void) _PyPreCmdline_SetPreConfig( const _PyPreCmdline *cmdline, _PyPreConfig *config); +PyAPI_FUNC(void) _PyPreCmdline_GetCoreConfig( + _PyPreCmdline *cmdline, + const _PyCoreConfig *config); +PyAPI_FUNC(void) _PyPreCmdline_SetCoreConfig( + const _PyPreCmdline *cmdline, + _PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline); @@ -77,7 +88,8 @@ PyAPI_FUNC(void) _Py_get_env_flag(_PyPreConfig *config, int *flag, const char *name); PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config, - const _PyArgv *args); + const _PyArgv *args, + const _PyCoreConfig *coreconfig); PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict); PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 130dfcc..ba5abb6 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -1336,16 +1336,30 @@ config_init_fs_encoding(_PyCoreConfig *config) * Py_xxx global configuration variables See _PyCoreConfig_ReadFromArgv() to parse also command line arguments. */ -_PyInitError -_PyCoreConfig_Read(_PyCoreConfig *config) +static _PyInitError +config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline) { _PyInitError err; - err = _Py_PreInitialize(); + err = _Py_PreInitializeFromConfig(config); + if (_Py_INIT_FAILED(err)) { + return err; + } + + _PyPreCmdline_GetPreConfig(cmdline, &_PyRuntime.preconfig); + _PyPreCmdline_GetCoreConfig(cmdline, config); + + err = _PyPreCmdline_Read(cmdline); if (_Py_INIT_FAILED(err)) { return err; } + _PyPreCmdline_SetCoreConfig(cmdline, config); + + if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) { + return _Py_INIT_NO_MEMORY(); + } + if (_PyPreConfig_Copy(&config->preconfig, &_PyRuntime.preconfig) < 0) { return _Py_INIT_NO_MEMORY(); } @@ -1454,6 +1468,41 @@ _PyCoreConfig_Read(_PyCoreConfig *config) } +static _PyInitError +config_read(_PyCoreConfig *config, const _PyPreCmdline *src_cmdline) +{ + _PyInitError err; + + err = _Py_PreInitializeFromConfig(config); + if (_Py_INIT_FAILED(err)) { + return err; + } + + _PyPreCmdline cmdline = _PyPreCmdline_INIT; + + if (src_cmdline) { + if (_PyPreCmdline_Copy(&cmdline, src_cmdline) < 0) { + err = _Py_INIT_NO_MEMORY(); + goto done; + } + } + + err = config_read_impl(config, &cmdline); + +done: + _PyPreCmdline_Clear(&cmdline); + return err; + +} + + +_PyInitError +_PyCoreConfig_Read(_PyCoreConfig *config) +{ + return config_read(config, NULL); +} + + static void config_init_stdio(const _PyCoreConfig *config) { @@ -2025,9 +2074,6 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline) } _PyPreCmdline_SetPreConfig(&cmdline->precmdline, &_PyRuntime.preconfig); - if (_PyWstrList_Extend(&config->xoptions, &cmdline->precmdline.xoptions) < 0) { - return _Py_INIT_NO_MEMORY(); - } err = config_parse_cmdline(config, cmdline, &need_usage); if (_Py_INIT_FAILED(err)) { @@ -2055,7 +2101,7 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline) return err; } - err = _PyCoreConfig_Read(config); + err = config_read(config, &cmdline->precmdline); if (_Py_INIT_FAILED(err)) { return err; } @@ -2090,7 +2136,7 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args) { _PyInitError err; - err = _Py_PreInitialize(); + err = _Py_PreInitializeFromConfig(config); if (_Py_INIT_FAILED(err)) { return err; } diff --git a/Python/preconfig.c b/Python/preconfig.c index c16f340..ac87a7a 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -110,6 +110,22 @@ _PyPreCmdline_Clear(_PyPreCmdline *cmdline) } +int +_PyPreCmdline_Copy(_PyPreCmdline *cmdline, const _PyPreCmdline *cmdline2) +{ + _PyPreCmdline_Clear(cmdline); + if (_PyWstrList_Copy(&cmdline->argv, &cmdline2->argv) < 0) { + return -1; + } + if (_PyWstrList_Copy(&cmdline->xoptions, &cmdline2->xoptions) < 0) { + return -1; + } + cmdline->use_environment = cmdline2->use_environment; + cmdline->isolated = cmdline2->isolated; + return 0; +} + + _PyInitError _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) { @@ -117,7 +133,7 @@ _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) } -static void +void _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config) { #define COPY_ATTR(ATTR) \ @@ -132,6 +148,36 @@ _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config) } +void +_PyPreCmdline_GetCoreConfig(_PyPreCmdline *cmdline, const _PyCoreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + if (config->preconfig.ATTR != -1) { \ + cmdline->ATTR = config->preconfig.ATTR; \ + } + + COPY_ATTR(use_environment); + COPY_ATTR(isolated); + +#undef COPY_ATTR +} + + +void +_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + if (config->preconfig.ATTR == -1 && cmdline->ATTR != -1) { \ + config->preconfig.ATTR = cmdline->ATTR; \ + } + + COPY_ATTR(use_environment); + COPY_ATTR(isolated); + +#undef COPY_ATTR +} + + /* --- _PyPreConfig ----------------------------------------------- */ void @@ -628,7 +674,8 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline) See _PyPreConfig_ReadFromArgv() to parse also command line arguments. */ _PyInitError -_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) +_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args, + const _PyCoreConfig *coreconfig) { _PyInitError err; _PyPreCmdline cmdline = _PyPreCmdline_INIT; @@ -642,8 +689,17 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) /* Set LC_CTYPE to the user preferred locale */ _Py_SetLocaleFromEnv(LC_CTYPE); + _PyPreConfig_GetGlobalConfig(config); + _PyPreCmdline_GetPreConfig(&cmdline, config); + if (coreconfig) { + _PyPreCmdline_GetCoreConfig(&cmdline, coreconfig); + if (config->dev_mode == -1) { + config->dev_mode = coreconfig->preconfig.dev_mode; + } + } + if (args) { err = _PyPreCmdline_SetArgv(&cmdline, args); if (_Py_INIT_FAILED(err)) { @@ -724,7 +780,7 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args) Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; #endif - err = _PyPreConfig_Read(config, args); + err = _PyPreConfig_Read(config, args, NULL); if (_Py_INIT_FAILED(err)) { goto done; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ea1b731..66cadc9 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -715,7 +715,9 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, static _PyInitError -pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config) +pyinit_preinit(_PyPreConfig *config, + const _PyPreConfig *src_config, + const _PyCoreConfig *coreconfig) { _PyInitError err; @@ -729,13 +731,17 @@ pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config) return _Py_INIT_OK(); } + if (!src_config && coreconfig) { + src_config = &coreconfig->preconfig; + } + if (src_config) { if (_PyPreConfig_Copy(config, src_config) < 0) { return _Py_INIT_ERR("failed to copy pre config"); } } - err = _PyPreConfig_Read(config, NULL); + err = _PyPreConfig_Read(config, NULL, coreconfig); if (_Py_INIT_FAILED(err)) { return err; } @@ -751,17 +757,27 @@ pyinit_preinit(_PyPreConfig *config, const _PyPreConfig *src_config) _PyInitError +_Py_PreInitialize(void) +{ + _PyPreConfig config = _PyPreConfig_INIT; + _PyInitError err = pyinit_preinit(&config, NULL, NULL); + _PyPreConfig_Clear(&config); + return err; +} + + +_PyInitError _Py_PreInitializeFromPreConfig(_PyPreConfig *config) { - return pyinit_preinit(config, NULL); + return pyinit_preinit(config, NULL, NULL); } _PyInitError -_Py_PreInitialize(void) +_Py_PreInitializeFromConfig(const _PyCoreConfig *coreconfig) { _PyPreConfig config = _PyPreConfig_INIT; - _PyInitError err = pyinit_preinit(&config, NULL); + _PyInitError err = pyinit_preinit(&config, NULL, coreconfig); _PyPreConfig_Clear(&config); return err; } @@ -814,16 +830,13 @@ _Py_InitializeCore(PyInterpreterState **interp_p, assert(src_config != NULL); - _PyCoreConfig local_config = _PyCoreConfig_INIT; - - err = pyinit_preinit(&local_config.preconfig, &src_config->preconfig); + err = _Py_PreInitializeFromConfig(src_config); if (_Py_INIT_FAILED(err)) { - goto done; + return err; } + _PyCoreConfig local_config = _PyCoreConfig_INIT; err = pyinit_coreconfig(&local_config, src_config, interp_p); - -done: _PyCoreConfig_Clear(&local_config); return err; } -- cgit v0.12