bpo-36444: Rework _Py_InitializeFromConfig() API (GH-12576)

This commit is contained in:
Victor Stinner 2019-03-27 13:40:14 +01:00 committed by GitHub
parent 364f0b0f19
commit 5ac27a50ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 218 additions and 201 deletions

View file

@ -1465,12 +1465,7 @@ static _PyInitError
config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
{
_PyInitError err;
const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
err = _PyPreCmdline_Read(cmdline, preconfig, config);
if (_Py_INIT_FAILED(err)) {
return err;
}
if (_PyPreCmdline_SetCoreConfig(cmdline, config) < 0) {
return _Py_INIT_NO_MEMORY();
@ -2016,6 +2011,35 @@ config_usage(int error, const wchar_t* program)
}
static _PyInitError
core_read_precmdline(_PyCoreConfig *config, const _PyArgv *args,
_PyPreCmdline *precmdline)
{
_PyInitError err;
if (args) {
err = _PyPreCmdline_SetArgv(precmdline, args);
if (_Py_INIT_FAILED(err)) {
return err;
}
}
_PyPreConfig preconfig = _PyPreConfig_INIT;
if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) {
err = _Py_INIT_NO_MEMORY();
goto done;
}
_PyCoreConfig_GetCoreConfig(&preconfig, config);
err = _PyPreCmdline_Read(precmdline, &preconfig);
done:
_PyPreConfig_Clear(&preconfig);
return err;
}
/* Read the configuration into _PyCoreConfig from:
* Command line arguments
@ -2026,7 +2050,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
{
_PyInitError err;
err = _Py_PreInitializeFromConfig(config);
err = _Py_PreInitializeFromCoreConfig(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
@ -2034,11 +2058,9 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
_PyCoreConfig_GetGlobalConfig(config);
_PyPreCmdline precmdline = _PyPreCmdline_INIT;
if (args) {
err = _PyPreCmdline_SetArgv(&precmdline, args);
if (_Py_INIT_FAILED(err)) {
goto done;
}
err = core_read_precmdline(config, args, &precmdline);
if (_Py_INIT_FAILED(err)) {
goto done;
}
if (config->program == NULL) {
@ -2048,12 +2070,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
}
}
const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
err = _PyPreCmdline_Read(&precmdline, preconfig, config);
if (_Py_INIT_FAILED(err)) {
goto done;
}
_PyCmdline cmdline;
memset(&cmdline, 0, sizeof(cmdline));

View file

@ -82,7 +82,7 @@ Py_FrozenMain(int argc, char **argv)
if (argc >= 1)
Py_SetProgramName(argv_copy[0]);
err = _Py_InitializeFromConfig(&config, NULL);
err = _Py_InitializeFromConfig(&config);
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any
memory: program_name is a constant string. */
if (_Py_INIT_FAILED(err)) {

View file

@ -148,22 +148,6 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
}
static void
_PyPreCmdline_GetCoreConfig(_PyPreCmdline *cmdline, const _PyCoreConfig *config)
{
#define COPY_ATTR(ATTR) \
if (config->ATTR != -1) { \
cmdline->ATTR = config->ATTR; \
}
COPY_ATTR(isolated);
COPY_ATTR(use_environment);
COPY_ATTR(dev_mode);
#undef COPY_ATTR
}
int
_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
{
@ -231,17 +215,12 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline)
_PyInitError
_PyPreCmdline_Read(_PyPreCmdline *cmdline,
const _PyPreConfig *preconfig,
const _PyCoreConfig *coreconfig)
const _PyPreConfig *preconfig)
{
if (preconfig) {
_PyPreCmdline_GetPreConfig(cmdline, preconfig);
}
if (coreconfig) {
_PyPreCmdline_GetCoreConfig(cmdline, coreconfig);
}
_PyInitError err = precmdline_parse_cmdline(cmdline);
if (_Py_INIT_FAILED(err)) {
return err;
@ -373,6 +352,23 @@ fail:
}
void
_PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
const _PyCoreConfig *core_config)
{
#define COPY_ATTR(ATTR) \
if (core_config->ATTR != -1) { \
config->ATTR = core_config->ATTR; \
}
COPY_ATTR(isolated);
COPY_ATTR(use_environment);
COPY_ATTR(dev_mode);
#undef COPY_ATTR
}
static void
_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
{
@ -640,12 +636,11 @@ preconfig_init_allocator(_PyPreConfig *config)
static _PyInitError
preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline,
const _PyCoreConfig *coreconfig)
preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
{
_PyInitError err;
err = _PyPreCmdline_Read(cmdline, config, coreconfig);
err = _PyPreCmdline_Read(cmdline, config);
if (_Py_INIT_FAILED(err)) {
return err;
}
@ -692,8 +687,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline,
- Py_xxx global configuration variables
- the LC_CTYPE locale */
_PyInitError
_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
const _PyCoreConfig *coreconfig)
_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
{
_PyInitError err;
@ -756,7 +750,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
#endif
err = preconfig_read(config, &cmdline, coreconfig);
err = preconfig_read(config, &cmdline);
if (_Py_INIT_FAILED(err)) {
goto done;
}

View file

@ -718,40 +718,35 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
static _PyInitError
pyinit_preinit(_PyPreConfig *config,
const _PyPreConfig *src_config,
const _PyCoreConfig *coreconfig)
preinit(const _PyPreConfig *src_config, const _PyArgv *args)
{
_PyInitError err;
_PyPreConfig local_config = _PyPreConfig_INIT;
if (!config) {
config = &local_config;
}
err = _PyRuntime_Initialize();
if (_Py_INIT_FAILED(err)) {
goto done;
return err;
}
if (_PyRuntime.pre_initialized) {
/* If it's already configured: ignored the new configuration */
err = _Py_INIT_OK();
goto done;
return _Py_INIT_OK();
}
_PyPreConfig config = _PyPreConfig_INIT;
if (src_config) {
if (_PyPreConfig_Copy(config, src_config) < 0) {
err = _Py_INIT_ERR("failed to copy pre config");
if (_PyPreConfig_Copy(&config, src_config) < 0) {
err = _Py_INIT_NO_MEMORY();
goto done;
}
}
err = _PyPreConfig_Read(config, NULL, coreconfig);
err = _PyPreConfig_Read(&config, args);
if (_Py_INIT_FAILED(err)) {
goto done;
}
err = _PyPreConfig_Write(config);
err = _PyPreConfig_Write(&config);
if (_Py_INIT_FAILED(err)) {
goto done;
}
@ -760,48 +755,55 @@ pyinit_preinit(_PyPreConfig *config,
err = _Py_INIT_OK();
done:
_PyPreConfig_Clear(&local_config);
_PyPreConfig_Clear(&config);
return err;
}
_PyInitError
_Py_PreInitialize(void)
_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
{
return pyinit_preinit(NULL, NULL, NULL);
_PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
return preinit(src_config, &args);
}
_PyInitError
_Py_PreInitializeFromPreConfig(const _PyPreConfig *src_config)
_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv)
{
return pyinit_preinit(NULL, src_config, NULL);
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
return preinit(src_config, &args);
}
_PyInitError
_Py_PreInitializeInPlace(_PyPreConfig *config)
_Py_PreInitialize(const _PyPreConfig *src_config)
{
return pyinit_preinit(config, NULL, NULL);
return preinit(src_config, NULL);
}
_PyInitError
_Py_PreInitializeFromConfig(const _PyCoreConfig *coreconfig)
_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig)
{
return pyinit_preinit(NULL, NULL, coreconfig);
_PyPreConfig config = _PyPreConfig_INIT;
_PyCoreConfig_GetCoreConfig(&config, coreconfig);
return _Py_PreInitialize(&config);
/* No need to clear config:
_PyCoreConfig_GetCoreConfig() doesn't allocate memory */
}
static _PyInitError
pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
pyinit_coreconfig(_PyCoreConfig *config,
const _PyCoreConfig *src_config,
const _PyArgv *args,
PyInterpreterState **interp_p)
{
if (_PyCoreConfig_Copy(config, src_config) < 0) {
return _Py_INIT_ERR("failed to copy core config");
}
_PyInitError err = _PyCoreConfig_Read(config, NULL);
_PyInitError err = _PyCoreConfig_Read(config, args);
if (_Py_INIT_FAILED(err)) {
return err;
}
@ -834,21 +836,23 @@ pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
*/
static _PyInitError
_Py_InitializeCore(const _PyCoreConfig *src_config,
const _PyArgv *args,
PyInterpreterState **interp_p)
{
assert(src_config != NULL);
_PyInitError err = _Py_PreInitializeFromConfig(src_config);
_PyInitError err = _Py_PreInitializeFromCoreConfig(src_config);
if (_Py_INIT_FAILED(err)) {
return err;
}
_PyCoreConfig local_config = _PyCoreConfig_INIT;
err = pyinit_coreconfig(&local_config, src_config, interp_p);
err = pyinit_coreconfig(&local_config, src_config, args, interp_p);
_PyCoreConfig_Clear(&local_config);
return err;
}
/* Py_Initialize() has already been called: update the main interpreter
configuration. Example of bpo-34008: Py_Main() called after
Py_Initialize(). */
@ -881,7 +885,7 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
* Other errors should be reported as normal Python exceptions with a
* non-zero return code.
*/
_PyInitError
static _PyInitError
_Py_InitializeMainInterpreter(PyInterpreterState *interp)
{
if (!_PyRuntime.core_initialized) {
@ -980,19 +984,15 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
#undef _INIT_DEBUG_PRINT
_PyInitError
_Py_InitializeFromConfig(const _PyCoreConfig *config,
PyInterpreterState **interp_p)
static _PyInitError
init_python(const _PyCoreConfig *config, const _PyArgv *args)
{
PyInterpreterState *interp = NULL;
_PyInitError err;
err = _Py_InitializeCore(config, &interp);
err = _Py_InitializeCore(config, args, &interp);
if (_Py_INIT_FAILED(err)) {
return err;
}
if (interp_p) {
*interp_p = interp;
}
config = &interp->core_config;
if (config->_init_main) {
@ -1006,6 +1006,29 @@ _Py_InitializeFromConfig(const _PyCoreConfig *config,
}
_PyInitError
_Py_InitializeFromArgs(const _PyCoreConfig *config, int argc, char **argv)
{
_PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
return init_python(config, &args);
}
_PyInitError
_Py_InitializeFromWideArgs(const _PyCoreConfig *config, int argc, wchar_t **argv)
{
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
return init_python(config, &args);
}
_PyInitError
_Py_InitializeFromConfig(const _PyCoreConfig *config)
{
return init_python(config, NULL);
}
void
Py_InitializeEx(int install_sigs)
{
@ -1017,7 +1040,7 @@ Py_InitializeEx(int install_sigs)
_PyCoreConfig config = _PyCoreConfig_INIT;
config.install_signal_handlers = install_sigs;
_PyInitError err = _Py_InitializeFromConfig(&config, NULL);
_PyInitError err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}