bpo-36763: Use PyConfig_Clear() (GH-14445)
Stop using "static PyConfig", PyConfig must now always use
dynamically allocated strings: use PyConfig_SetString(),
PyConfig_SetArgv() and PyConfig_Clear().
(cherry picked from commit 67310023f2
)
Co-authored-by: Victor Stinner <vstinner@redhat.com>
This commit is contained in:
parent
96f581cf9d
commit
4c227e6a56
|
@ -695,10 +695,19 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
|
||||
'pycache_prefix': 'conf_pycache_prefix',
|
||||
'program_name': './conf_program_name',
|
||||
'argv': ['-c', 'arg2'],
|
||||
'argv': ['-c', 'arg2', ],
|
||||
'parse_argv': 1,
|
||||
'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'],
|
||||
'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
|
||||
'xoptions': [
|
||||
'config_xoption1=3',
|
||||
'config_xoption2=',
|
||||
'config_xoption3',
|
||||
'cmdline_xoption',
|
||||
],
|
||||
'warnoptions': [
|
||||
'config_warnoption',
|
||||
'cmdline_warnoption',
|
||||
'default::BytesWarning',
|
||||
],
|
||||
'run_command': 'pass\n',
|
||||
|
||||
'site_import': 0,
|
||||
|
|
|
@ -62,7 +62,7 @@ pymain_init(const _PyArgv *args)
|
|||
PyConfig config;
|
||||
status = PyConfig_InitPythonConfig(&config);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* pass NULL as the config: config is read from command line arguments,
|
||||
|
@ -74,14 +74,18 @@ pymain_init(const _PyArgv *args)
|
|||
status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
|
||||
}
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
return _PyStatus_OK();
|
||||
status = _PyStatus_OK();
|
||||
|
||||
done:
|
||||
PyConfig_Clear(&config);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -329,6 +329,56 @@ static int test_init_initialize_config(void)
|
|||
}
|
||||
|
||||
|
||||
static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str)
|
||||
{
|
||||
PyStatus status = PyConfig_SetString(config, config_str, str);
|
||||
if (PyStatus_Exception(status)) {
|
||||
PyConfig_Clear(config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
|
||||
{
|
||||
PyStatus status = PyConfig_SetArgv(config, argc, argv);
|
||||
if (PyStatus_Exception(status)) {
|
||||
PyConfig_Clear(config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
config_set_wide_string_list(PyConfig *config, PyWideStringList *list,
|
||||
Py_ssize_t length, wchar_t **items)
|
||||
{
|
||||
PyStatus status = PyConfig_SetWideStringList(config, list, length, items);
|
||||
if (PyStatus_Exception(status)) {
|
||||
PyConfig_Clear(config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void config_set_program_name(PyConfig *config)
|
||||
{
|
||||
/* Use path starting with "./" avoids a search along the PATH */
|
||||
const wchar_t *program_name = L"./_testembed";
|
||||
config_set_string(config, &config->program_name, program_name);
|
||||
}
|
||||
|
||||
|
||||
static void init_from_config_clear(PyConfig *config)
|
||||
{
|
||||
PyStatus status = Py_InitializeFromConfig(config);
|
||||
PyConfig_Clear(config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int check_init_compat_config(int preinit)
|
||||
{
|
||||
PyStatus status;
|
||||
|
@ -345,12 +395,8 @@ static int check_init_compat_config(int preinit)
|
|||
|
||||
PyConfig config;
|
||||
_PyConfig_InitCompatConfig(&config);
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
|
@ -438,7 +484,6 @@ static int test_init_from_config(void)
|
|||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
/* Test Py_InitializeFromConfig() */
|
||||
PyConfig config;
|
||||
_PyConfig_InitCompatConfig(&config);
|
||||
config.install_signal_handlers = 0;
|
||||
|
@ -468,34 +513,37 @@ static int test_init_from_config(void)
|
|||
config.malloc_stats = 1;
|
||||
|
||||
putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
|
||||
config.pycache_prefix = L"conf_pycache_prefix";
|
||||
config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix");
|
||||
|
||||
Py_SetProgramName(L"./globalvar");
|
||||
config.program_name = L"./conf_program_name";
|
||||
config_set_string(&config, &config.program_name, L"./conf_program_name");
|
||||
|
||||
static wchar_t* argv[] = {
|
||||
wchar_t* argv[] = {
|
||||
L"python3",
|
||||
L"-W",
|
||||
L"cmdline_warnoption",
|
||||
L"-X",
|
||||
L"cmdline_xoption",
|
||||
L"-c",
|
||||
L"pass",
|
||||
L"arg2",
|
||||
};
|
||||
config.argv.length = Py_ARRAY_LENGTH(argv);
|
||||
config.argv.items = argv;
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config.parse_argv = 1;
|
||||
|
||||
static wchar_t* xoptions[3] = {
|
||||
L"xoption1=3",
|
||||
L"xoption2=",
|
||||
L"xoption3",
|
||||
wchar_t* xoptions[3] = {
|
||||
L"config_xoption1=3",
|
||||
L"config_xoption2=",
|
||||
L"config_xoption3",
|
||||
};
|
||||
config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
|
||||
config.xoptions.items = xoptions;
|
||||
config_set_wide_string_list(&config, &config.xoptions,
|
||||
Py_ARRAY_LENGTH(xoptions), xoptions);
|
||||
|
||||
static wchar_t* warnoptions[1] = {
|
||||
L"error::ResourceWarning",
|
||||
wchar_t* warnoptions[1] = {
|
||||
L"config_warnoption",
|
||||
};
|
||||
config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
|
||||
config.warnoptions.items = warnoptions;
|
||||
config_set_wide_string_list(&config, &config.warnoptions,
|
||||
Py_ARRAY_LENGTH(warnoptions), warnoptions);
|
||||
|
||||
/* FIXME: test pythonpath_env */
|
||||
/* FIXME: test home */
|
||||
|
@ -544,22 +592,20 @@ static int test_init_from_config(void)
|
|||
Force it to 0 through the config. */
|
||||
config.legacy_windows_stdio = 0;
|
||||
#endif
|
||||
config.stdio_encoding = L"iso8859-1";
|
||||
config.stdio_errors = L"replace";
|
||||
config_set_string(&config, &config.stdio_encoding, L"iso8859-1");
|
||||
config_set_string(&config, &config.stdio_errors, L"replace");
|
||||
|
||||
putenv("PYTHONNOUSERSITE=");
|
||||
Py_NoUserSiteDirectory = 0;
|
||||
config.user_site_directory = 0;
|
||||
|
||||
config.check_hash_pycs_mode = L"always";
|
||||
config_set_string(&config, &config.check_hash_pycs_mode, L"always");
|
||||
|
||||
Py_FrozenFlag = 0;
|
||||
config.pathconfig_warnings = 0;
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -576,7 +622,9 @@ static int check_init_parse_argv(int parse_argv)
|
|||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
static wchar_t* argv[] = {
|
||||
config.parse_argv = parse_argv;
|
||||
|
||||
wchar_t* argv[] = {
|
||||
L"./argv0",
|
||||
L"-E",
|
||||
L"-c",
|
||||
|
@ -585,15 +633,9 @@ static int check_init_parse_argv(int parse_argv)
|
|||
L"-v",
|
||||
L"arg3",
|
||||
};
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
config.argv.length = Py_ARRAY_LENGTH(argv);
|
||||
config.argv.items = argv;
|
||||
config.parse_argv = parse_argv;
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -664,12 +706,10 @@ static int test_init_python_env(void)
|
|||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -723,14 +763,10 @@ static int test_init_isolated_flag(void)
|
|||
Py_IsolatedFlag = 0;
|
||||
config.isolated = 1;
|
||||
|
||||
/* Use path starting with "./" avoids a search along the PATH */
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
config_set_program_name(&config);
|
||||
set_all_env_vars();
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -753,13 +789,10 @@ static int test_preinit_isolated1(void)
|
|||
|
||||
PyConfig config;
|
||||
_PyConfig_InitCompatConfig(&config);
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
config_set_program_name(&config);
|
||||
set_all_env_vars();
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -787,14 +820,10 @@ static int test_preinit_isolated2(void)
|
|||
Py_IsolatedFlag = 0;
|
||||
config.isolated = 1;
|
||||
|
||||
/* Use path starting with "./" avoids a search along the PATH */
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
config_set_program_name(&config);
|
||||
set_all_env_vars();
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -819,44 +848,28 @@ static int test_preinit_dont_parse_argv(void)
|
|||
L"script.py"};
|
||||
status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
PyConfig config;
|
||||
|
||||
status = PyConfig_InitIsolatedConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
config.isolated = 0;
|
||||
|
||||
/* Pre-initialize implicitly using argv: make sure that -X dev
|
||||
is used to configure the allocation in preinitialization */
|
||||
status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = PyConfig_SetString(&config, &config.program_name,
|
||||
L"./_testembed");
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
PyConfig_Clear(&config);
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -867,36 +880,20 @@ static int test_preinit_parse_argv(void)
|
|||
|
||||
status = PyConfig_InitPythonConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
/* Pre-initialize implicitly using argv: make sure that -X dev
|
||||
is used to configure the allocation in preinitialization */
|
||||
wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
|
||||
status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = PyConfig_SetString(&config, &config.program_name,
|
||||
L"./_testembed");
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
PyConfig_Clear(&config);
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -955,13 +952,8 @@ static int check_preinit_isolated_config(int preinit)
|
|||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
rt_preconfig = &_PyRuntime.preconfig;
|
||||
assert(rt_preconfig->isolated == 1);
|
||||
|
@ -1017,12 +1009,9 @@ static int check_init_python_config(int preinit)
|
|||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config.program_name = L"./_testembed";
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -1061,11 +1050,8 @@ static int test_init_dont_configure_locale(void)
|
|||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config.program_name = L"./_testembed";
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
|
@ -1084,11 +1070,9 @@ static int test_init_dev_mode(void)
|
|||
putenv("PYTHONFAULTHANDLER=");
|
||||
putenv("PYTHONMALLOC=");
|
||||
config.dev_mode = 1;
|
||||
config.program_name = L"./_testembed";
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -1278,16 +1262,9 @@ static int test_init_read_set(void)
|
|||
}
|
||||
|
||||
/* override executable computed by PyConfig_Read() */
|
||||
status = PyConfig_SetString(&config, &config.executable, L"my_executable");
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto fail;
|
||||
}
|
||||
config_set_string(&config, &config.executable, L"my_executable");
|
||||
init_from_config_clear(&config);
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
PyConfig_Clear(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto fail;
|
||||
}
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
|
@ -1297,19 +1274,18 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
wchar_t *init_main_argv[] = {
|
||||
static void configure_init_main(PyConfig *config)
|
||||
{
|
||||
wchar_t* argv[] = {
|
||||
L"python3", L"-c",
|
||||
(L"import _testinternalcapi, json; "
|
||||
L"print(json.dumps(_testinternalcapi.get_configs()))"),
|
||||
L"arg2"};
|
||||
|
||||
|
||||
static void configure_init_main(PyConfig *config)
|
||||
{
|
||||
config->argv.length = Py_ARRAY_LENGTH(init_main_argv);
|
||||
config->argv.items = init_main_argv;
|
||||
config->parse_argv = 1;
|
||||
config->program_name = L"./python3";
|
||||
|
||||
config_set_argv(config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config_set_string(config, &config->program_name, L"./python3");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1322,11 +1298,7 @@ static int test_init_run_main(void)
|
|||
Py_ExitStatusException(status);
|
||||
}
|
||||
configure_init_main(&config);
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
return Py_RunMain();
|
||||
}
|
||||
|
@ -1343,11 +1315,7 @@ static int test_init_main(void)
|
|||
}
|
||||
configure_init_main(&config);
|
||||
config._init_main = 0;
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
init_from_config_clear(&config);
|
||||
|
||||
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
|
||||
int res = PyRun_SimpleString(
|
||||
|
@ -1374,35 +1342,19 @@ static int test_run_main(void)
|
|||
|
||||
status = PyConfig_InitPythonConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
wchar_t *argv[] = {L"python3", L"-c",
|
||||
(L"import sys; "
|
||||
L"print(f'Py_RunMain(): sys.argv={sys.argv}')"),
|
||||
L"arg2"};
|
||||
status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = PyConfig_SetString(&config, &config.program_name,
|
||||
L"./python3");
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
if (PyStatus_Exception(status)) {
|
||||
goto failed;
|
||||
}
|
||||
PyConfig_Clear(&config);
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config_set_string(&config, &config.program_name, L"./python3");
|
||||
init_from_config_clear(&config);
|
||||
|
||||
return Py_RunMain();
|
||||
|
||||
failed:
|
||||
PyConfig_Clear(&config);
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue