Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/internal/pycore_coreconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config,
PyObject *dict);
PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config,
const _PyArgv *args);
PyAPI_FUNC(void) _PyPreConfig_Write(const _PyPreConfig *config);
PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config);


/* --- _PyCoreConfig ---------------------------------------------- */
Expand Down
3 changes: 1 addition & 2 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ preconfig_read_write(_PyPreConfig *config, const _PyArgv *args)
return err;
}

_PyPreConfig_Write(config);
return _Py_INIT_OK();
return _PyPreConfig_Write(config);
}


Expand Down
30 changes: 29 additions & 1 deletion Python/preconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,9 +741,35 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args)
}


void
static _PyInitError
_PyPreConfig_Reconfigure(const _PyPreConfig *config)
{
if (config->allocator != NULL) {
const char *allocator = _PyMem_GetAllocatorsName();
if (allocator == NULL || strcmp(config->allocator, allocator) != 0) {
return _Py_INIT_USER_ERR("cannot modify memory allocator "
"after first Py_Initialize()");
}
}
return _Py_INIT_OK();
}


_PyInitError
_PyPreConfig_Write(const _PyPreConfig *config)
{
if (_PyRuntime.core_initialized) {
/* bpo-34008: Calling Py_Main() after Py_Initialize() ignores
the new configuration. */
return _PyPreConfig_Reconfigure(config);
}

if (config->allocator != NULL) {
if (_PyMem_SetupAllocators(config->allocator) < 0) {
return _Py_INIT_USER_ERR("Unknown PYTHONMALLOC allocator");
}
}

_PyPreConfig_SetGlobalConfig(config);

if (config->coerce_c_locale) {
Expand All @@ -752,4 +778,6 @@ _PyPreConfig_Write(const _PyPreConfig *config)

/* Set LC_CTYPE to the user preferred locale */
_Py_SetLocaleFromEnv(LC_CTYPE);

return _Py_INIT_OK();
}
103 changes: 64 additions & 39 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,16 +480,6 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p,
}
*interp_p = interp;

/* bpo-34008: For backward compatibility reasons, calling Py_Main() after
Py_Initialize() ignores the new configuration. */
if (core_config->preconfig.allocator != NULL) {
const char *allocator = _PyMem_GetAllocatorsName();
if (allocator == NULL || strcmp(core_config->preconfig.allocator, allocator) != 0) {
return _Py_INIT_USER_ERR("cannot modify memory allocator "
"after first Py_Initialize()");
}
}

_PyCoreConfig_SetGlobalConfig(core_config);

if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) {
Expand Down Expand Up @@ -521,12 +511,6 @@ pycore_init_runtime(const _PyCoreConfig *core_config)
return err;
}

if (core_config->preconfig.allocator != NULL) {
if (_PyMem_SetupAllocators(core_config->preconfig.allocator) < 0) {
return _Py_INIT_USER_ERR("Unknown PYTHONMALLOC allocator");
}
}

/* Py_Finalize leaves _Py_Finalizing set in order to help daemon
* threads behave a little more gracefully at interpreter shutdown.
* We clobber it here so the new interpreter can start with a clean
Expand Down Expand Up @@ -728,6 +712,65 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
return _Py_INIT_OK();
}


static _PyInitError
pyinit_preconfig(_PyPreConfig *preconfig, const _PyPreConfig *src_preconfig)
{
_PyInitError err;
PyMemAllocatorEx old_alloc;

/* Set LC_CTYPE to the user preferred locale */
_Py_SetLocaleFromEnv(LC_CTYPE);

_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_PyPreConfig_Copy(preconfig, src_preconfig) >= 0) {
err = _PyPreConfig_Read(preconfig);
}
else {
err = _Py_INIT_ERR("failed to copy pre config");
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

if (_Py_INIT_FAILED(err)) {
return err;
}

return _PyPreConfig_Write(preconfig);
}


static _PyInitError
pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
PyInterpreterState **interp_p)
{
PyMemAllocatorEx old_alloc;
_PyInitError err;

/* Set LC_CTYPE to the user preferred locale */
_Py_SetLocaleFromEnv(LC_CTYPE);

_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_PyCoreConfig_Copy(config, src_config) >= 0) {
err = _PyCoreConfig_Read(config, NULL);
}
else {
err = _Py_INIT_ERR("failed to copy core config");
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

if (_Py_INIT_FAILED(err)) {
return err;
}

if (!_PyRuntime.core_initialized) {
return _Py_InitializeCore_impl(interp_p, config);
}
else {
return _Py_Initialize_ReconfigureCore(interp_p, config);
}
}


/* Begin interpreter initialization
*
* On return, the first thread and interpreter state have been created,
Expand All @@ -749,41 +792,23 @@ _PyInitError
_Py_InitializeCore(PyInterpreterState **interp_p,
const _PyCoreConfig *src_config)
{
assert(src_config != NULL);

PyMemAllocatorEx old_alloc;
_PyInitError err;

/* Copy the configuration, since _PyCoreConfig_Read() modifies it
(and the input configuration is read only). */
_PyCoreConfig config = _PyCoreConfig_INIT;

/* Set LC_CTYPE to the user preferred locale */
_Py_SetLocaleFromEnv(LC_CTYPE);
assert(src_config != NULL);

_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_PyCoreConfig_Copy(&config, src_config) >= 0) {
err = _PyCoreConfig_Read(&config, NULL);
}
else {
err = _Py_INIT_ERR("failed to copy core config");
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyCoreConfig local_config = _PyCoreConfig_INIT;

err = pyinit_preconfig(&local_config.preconfig, &src_config->preconfig);
if (_Py_INIT_FAILED(err)) {
goto done;
}

if (!_PyRuntime.core_initialized) {
err = _Py_InitializeCore_impl(interp_p, &config);
}
else {
err = _Py_Initialize_ReconfigureCore(interp_p, &config);
}
err = pyinit_coreconfig(&local_config, src_config, interp_p);

done:
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyCoreConfig_Clear(&config);
_PyCoreConfig_Clear(&local_config);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

return err;
Expand Down