mirror of
https://github.com/python/cpython.git
synced 2025-09-13 12:17:24 +00:00
bpo-32030: Add _PyCoreConfig_Copy() (#4874)
Each interpreter now has its core_config and main_config copy: * Add _PyCoreConfig_Copy() and _PyMainInterpreterConfig_Copy() * Move _PyCoreConfig_Read(), _PyCoreConfig_Clear() and _PyMainInterpreterConfig_Clear() from Python/pylifecycle.c to Modules/main.c * Fix _Py_InitializeEx_Private(): call _PyCoreConfig_ReadEnv() before _Py_InitializeCore()
This commit is contained in:
parent
358e5e17a5
commit
da273412c4
4 changed files with 197 additions and 84 deletions
148
Modules/main.c
148
Modules/main.c
|
@ -1914,6 +1914,154 @@ pymain_parse_cmdline_envvars(_PyMain *pymain)
|
|||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
_PyInitError
|
||||
_PyCoreConfig_Read(_PyCoreConfig *config)
|
||||
{
|
||||
if (config->program_name == NULL) {
|
||||
#ifdef MS_WINDOWS
|
||||
const wchar_t *program_name = L"python";
|
||||
#else
|
||||
const wchar_t *program_name = L"python3";
|
||||
#endif
|
||||
config->program_name = _PyMem_RawWcsdup(program_name);
|
||||
if (config->program_name == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyCoreConfig_Clear(_PyCoreConfig *config)
|
||||
{
|
||||
#define CLEAR(ATTR) \
|
||||
do { \
|
||||
PyMem_RawFree(ATTR); \
|
||||
ATTR = NULL; \
|
||||
} while (0)
|
||||
|
||||
CLEAR(config->module_search_path_env);
|
||||
CLEAR(config->home);
|
||||
CLEAR(config->program_name);
|
||||
#undef CLEAR
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||
{
|
||||
_PyCoreConfig_Clear(config);
|
||||
|
||||
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
|
||||
COPY_ATTR(ignore_environment);
|
||||
COPY_ATTR(use_hash_seed);
|
||||
COPY_ATTR(hash_seed);
|
||||
COPY_ATTR(_disable_importlib);
|
||||
COPY_ATTR(allocator);
|
||||
COPY_ATTR(dev_mode);
|
||||
COPY_ATTR(faulthandler);
|
||||
COPY_ATTR(tracemalloc);
|
||||
COPY_ATTR(import_time);
|
||||
COPY_ATTR(show_ref_count);
|
||||
COPY_ATTR(show_alloc_count);
|
||||
COPY_ATTR(dump_refs);
|
||||
COPY_ATTR(malloc_stats);
|
||||
COPY_ATTR(utf8_mode);
|
||||
#undef COPY_ATTR
|
||||
|
||||
#define COPY_STR_ATTR(ATTR) \
|
||||
do { \
|
||||
if (config2->ATTR != NULL) { \
|
||||
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
|
||||
if (config->ATTR == NULL) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_STR_ATTR(module_search_path_env);
|
||||
COPY_STR_ATTR(home);
|
||||
COPY_STR_ATTR(program_name);
|
||||
#undef COPY_STR_ATTR
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
|
||||
{
|
||||
Py_CLEAR(config->argv);
|
||||
Py_CLEAR(config->module_search_path);
|
||||
Py_CLEAR(config->warnoptions);
|
||||
Py_CLEAR(config->xoptions);
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
config_copy_attr(PyObject *obj)
|
||||
{
|
||||
if (PyUnicode_Check(obj)) {
|
||||
Py_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
else if (PyList_Check(obj)) {
|
||||
return PyList_GetSlice(obj, 0, Py_SIZE(obj));
|
||||
}
|
||||
else if (PyDict_Check(obj)) {
|
||||
/* The dict type is used for xoptions. Make the assumption that keys
|
||||
and values are immutables */
|
||||
return PyDict_Copy(obj);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"cannot copy config attribute of type %.200s",
|
||||
Py_TYPE(obj)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
|
||||
const _PyMainInterpreterConfig *config2)
|
||||
{
|
||||
_PyMainInterpreterConfig_Clear(config);
|
||||
|
||||
#define COPY_ATTR(ATTR) \
|
||||
do { \
|
||||
if (config2->ATTR != NULL) { \
|
||||
config->ATTR = config_copy_attr(config2->ATTR); \
|
||||
if (config->ATTR == NULL) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_ATTR(argv);
|
||||
COPY_ATTR(module_search_path);
|
||||
COPY_ATTR(warnoptions);
|
||||
COPY_ATTR(xoptions);
|
||||
#undef COPY_ATTR
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static PyObject *
|
||||
config_create_path_list(const wchar_t *path, wchar_t delim)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue