summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-07-01 17:52:45 (GMT)
committerGitHub <noreply@github.com>2019-07-01 17:52:45 (GMT)
commit67310023f299b5a2fad71fca449b46d280036690 (patch)
tree50b2da097996f106b68b802acbd579a41950c3e2
parente6b64b756f940147728ea7808fb686ffcae89176 (diff)
downloadcpython-67310023f299b5a2fad71fca449b46d280036690.zip
cpython-67310023f299b5a2fad71fca449b46d280036690.tar.gz
cpython-67310023f299b5a2fad71fca449b46d280036690.tar.bz2
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().
-rw-r--r--Lib/test/test_embed.py15
-rw-r--r--Modules/main.c12
-rw-r--r--Programs/_freeze_importlib.c2
-rw-r--r--Programs/_testembed.c308
4 files changed, 151 insertions, 186 deletions
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index e1cf4be..b2cd550 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -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,
diff --git a/Modules/main.c b/Modules/main.c
index 853afed..b126f45 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -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;
}
diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c
index 13375b0..74735f2 100644
--- a/Programs/_freeze_importlib.c
+++ b/Programs/_freeze_importlib.c
@@ -88,7 +88,7 @@ main(int argc, char *argv[])
config.site_import = 0;
status = PyConfig_SetString(&config, &config.program_name,
- L"./_freeze_importlib");
+ L"./_freeze_importlib");
if (PyStatus_Exception(status)) {
PyConfig_Clear(&config);
Py_ExitStatusException(status);
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 9633f46..856144b 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -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[] = {
- 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;
+ wchar_t* argv[] = {
+ L"python3", L"-c",
+ (L"import _testinternalcapi, json; "
+ L"print(json.dumps(_testinternalcapi.get_configs()))"),
+ L"arg2"};
+
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);
}