bpo-36763: Add _PyCoreConfig_InitPythonConfig() (GH-13388)

Add new functions to get the Python interpreter behavior:

* _PyPreConfig_InitPythonConfig()
* _PyCoreConfig_InitPythonConfig()

Add new functions to get an isolated configuration:

* _PyPreConfig_InitIsolatedConfig()
* _PyCoreConfig_InitIsolatedConfig()

Replace _PyPreConfig_INIT and _PyCoreConfig_INIT with new functions
_PyPreConfig_Init() and _PyCoreConfig_Init().

_PyCoreConfig: set configure_c_stdio and parse_argv to 0 by default
to behave as Python 3.6 in the default configuration.

_PyCoreConfig_Read() no longer sets coerce_c_locale_warn to 1 if it's
equal to 0. coerce_c_locale_warn must now be set to -1 (ex: using
_PyCoreConfig_InitPythonConfig()) to enable C locale coercion
warning.

Add unit tests for _PyCoreConfig_InitPythonConfig()
and _PyCoreConfig_InitIsolatedConfig().

Changes:

* Rename _PyCoreConfig_GetCoreConfig() to _PyPreConfig_GetCoreConfig()
* Fix core_read_precmdline(): handle parse_argv=0
* Fix _Py_PreInitializeFromCoreConfig(): pass coreconfig.argv
  to _Py_PreInitializeFromPyArgv(), except if parse_argv=0
This commit is contained in:
Victor Stinner 2019-05-17 19:01:14 +02:00 committed by GitHub
parent b16b4e4592
commit cab5d0741e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 362 additions and 91 deletions

View File

@ -86,12 +86,18 @@ typedef struct {
If it is equal to 1, LC_CTYPE locale is read to decide it it should be
coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2
if the LC_CTYPE locale must be coerced. */
if the LC_CTYPE locale must be coerced.
Disable by default (set to 0). Set it to -1 to let Python decides if it
should be enabled or not. */
int coerce_c_locale;
/* Emit a warning if the LC_CTYPE locale is coerced?
Disabled by default. Set to 1 by PYTHONCOERCECLOCALE=warn. */
Set to 1 by PYTHONCOERCECLOCALE=warn.
Disable by default (set to 0). Set it to -1 to let Python decides if it
should be enabled or not. */
int coerce_c_locale_warn;
#ifdef MS_WINDOWS
@ -116,7 +122,10 @@ typedef struct {
Set to 0 by "-X utf8=0" and PYTHONUTF8=0.
If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or
"POSIX", otherwise inherit Py_UTF8Mode value. */
"POSIX", otherwise it is set to 0.
If equals to -2, inherit Py_UTF8Mode value value (which is equal to 0
by default). */
int utf8_mode;
int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */
@ -138,9 +147,14 @@ typedef struct {
._config_version = _Py_CONFIG_VERSION, \
.isolated = -1, \
.use_environment = -1, \
.utf8_mode = -2, \
.dev_mode = -1, \
.allocator = PYMEM_ALLOCATOR_NOT_SET}
PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config);
PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config);
PyAPI_FUNC(void) _PyPreConfig_InitIsolateConfig(_PyPreConfig *config);
/* --- _PyCoreConfig ---------------------------------------------- */
@ -213,8 +227,8 @@ typedef struct {
/* Command line arguments (sys.argv).
By default, Python command line arguments are parsed and then stripped
from argv. Set parse_argv to 0 to avoid that.
Set parse_argv to 1 to parse argv as Python command line arguments
and then strip Python arguments from argv.
If argv is empty, an empty string is added to ensure that sys.argv
always exists and is never empty. */
@ -442,7 +456,7 @@ typedef struct {
.faulthandler = -1, \
.tracemalloc = -1, \
.use_module_search_paths = 0, \
.parse_argv = 1, \
.parse_argv = 0, \
.site_import = -1, \
.bytes_warning = -1, \
.inspect = -1, \
@ -453,7 +467,7 @@ typedef struct {
.verbose = -1, \
.quiet = -1, \
.user_site_directory = -1, \
.configure_c_stdio = 1, \
.configure_c_stdio = 0, \
.buffered_stdio = -1, \
._install_importlib = 1, \
.check_hash_pycs_mode = NULL, \
@ -461,6 +475,10 @@ typedef struct {
._init_main = 1}
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
PyAPI_FUNC(void) _PyCoreConfig_Init(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolateConfig(_PyCoreConfig *config);
#ifdef __cplusplus
}
#endif

View File

@ -88,10 +88,13 @@ PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline,
/* --- _PyPreConfig ----------------------------------------------- */
PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config);
PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config);
PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config);
PyAPI_FUNC(int) _PyPreConfig_Copy(_PyPreConfig *config,
const _PyPreConfig *config2);
PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config);
PyAPI_FUNC(void) _PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
PyAPI_FUNC(void) _PyPreConfig_GetCoreConfig(_PyPreConfig *config,
const _PyCoreConfig *core_config);
PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config,
const _PyArgv *args);
@ -101,6 +104,8 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config);
/* --- _PyCoreConfig ---------------------------------------------- */
PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy(
_PyCoreConfig *config,
const _PyCoreConfig *config2);

View File

@ -307,7 +307,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'pycache_prefix': None,
'program_name': GET_DEFAULT_CONFIG,
'parse_argv': 1,
'parse_argv': 0,
'argv': [""],
'xoptions': [],
@ -333,7 +333,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'verbose': 0,
'quiet': 0,
'user_site_directory': 1,
'configure_c_stdio': 1,
'configure_c_stdio': 0,
'buffered_stdio': 1,
'stdio_encoding': GET_DEFAULT_CONFIG,
@ -588,6 +588,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'pycache_prefix': 'conf_pycache_prefix',
'program_name': './conf_program_name',
'argv': ['-c', 'arg2'],
'parse_argv': 1,
'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'],
'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
'run_command': 'pass\n',
@ -600,7 +601,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'write_bytecode': 0,
'verbose': 1,
'quiet': 1,
'configure_c_stdio': 0,
'configure_c_stdio': 1,
'buffered_stdio': 0,
'user_site_directory': 0,
'faulthandler': 1,
@ -661,14 +662,14 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
}
self.check_config("init_dev_mode", config, preconfig)
def test_init_isolated(self):
def test_init_isolated_flag(self):
preconfig = {}
config = {
'isolated': 1,
'use_environment': 0,
'user_site_directory': 0,
}
self.check_config("init_isolated", config, preconfig)
self.check_config("init_isolated_flag", config, preconfig)
def test_preinit_isolated1(self):
# _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
@ -690,6 +691,25 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
}
self.check_config("preinit_isolated2", config, preconfig)
def test_init_isolated_config(self):
preconfig = {}
config = {
'isolated': 1,
'use_environment': 0,
'user_site_directory': 0,
'install_signal_handlers': 0,
'pathconfig_warnings': 0,
}
self.check_config("init_isolated_config", config, preconfig)
def test_init_python_config(self):
preconfig = {}
config = {
'configure_c_stdio': 1,
'parse_argv': 1,
}
self.check_config("init_python_config", config, preconfig)
def test_init_read_set(self):
preconfig = {}
core_config = {
@ -707,6 +727,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'argv': ['-c', 'arg2'],
'program_name': './python3',
'run_command': code + '\n',
'parse_argv': 1,
}
self.check_config("init_run_main", core_config, preconfig)
@ -718,15 +739,26 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'argv': ['-c', 'arg2'],
'program_name': './python3',
'run_command': code + '\n',
'parse_argv': 1,
'_init_main': 0,
}
self.check_config("init_main", core_config, preconfig,
stderr="Run Python code before _Py_InitializeMain")
def test_init_parse_argv(self):
core_config = {
'argv': ['-c', 'arg1', '-v', 'arg3'],
'program_name': './argv0',
'parse_argv': 1,
'run_command': 'pass\n',
'use_environment': 0,
}
self.check_config("init_parse_argv", core_config, {})
def test_init_dont_parse_argv(self):
core_config = {
'argv': ['-v', '-c', 'arg1', '-W', 'arg2'],
'parse_argv': 0,
'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'],
'program_name': './argv0',
}
self.check_config("init_dont_parse_argv", core_config, {})

View File

@ -52,23 +52,28 @@ pymain_init(const _PyArgv *args)
fedisableexcept(FE_OVERFLOW);
#endif
_PyPreConfig preconfig = _PyPreConfig_INIT;
/* Set to -1 to enable them depending on the LC_CTYPE locale and the
environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE) */
preconfig.coerce_c_locale = -1;
preconfig.utf8_mode = -1;
_PyPreConfig preconfig;
_PyPreConfig_InitPythonConfig(&preconfig);
err = _Py_PreInitializeFromPyArgv(&preconfig, args);
if (_Py_INIT_FAILED(err)) {
return err;
}
_PyCoreConfig config;
err = _PyCoreConfig_InitPythonConfig(&config);
if (_Py_INIT_FAILED(err)) {
return err;
}
/* pass NULL as the config: config is read from command line arguments,
environment variables, configuration files */
if (args->use_bytes_argv) {
return _Py_InitializeFromArgs(NULL, args->argc, args->bytes_argv);
return _Py_InitializeFromArgs(&config,
args->argc, args->bytes_argv);
}
else {
return _Py_InitializeFromWideArgs(NULL, args->argc, args->wchar_argv);
return _Py_InitializeFromWideArgs(&config,
args->argc, args->wchar_argv);
}
}

View File

@ -76,7 +76,8 @@ main(int argc, char *argv[])
}
text[text_size] = '\0';
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
config.use_environment = 0;
config.user_site_directory = 0;
config.site_import = 0;

View File

@ -291,7 +291,9 @@ static int test_initialize_twice(void)
static int test_initialize_pymain(void)
{
wchar_t *argv[] = {L"PYTHON", L"-c",
L"import sys; print(f'Py_Main() after Py_Initialize: sys.argv={sys.argv}')",
(L"import sys; "
L"print(f'Py_Main() after Py_Initialize: "
L"sys.argv={sys.argv}')"),
L"arg2"};
_testembed_Py_Initialize();
@ -376,7 +378,8 @@ static int test_init_from_config(void)
{
_PyInitError err;
_PyPreConfig preconfig = _PyPreConfig_INIT;
_PyPreConfig preconfig;
_PyPreConfig_Init(&preconfig);
putenv("PYTHONMALLOC=malloc_debug");
preconfig.allocator = PYMEM_ALLOCATOR_MALLOC;
@ -391,7 +394,8 @@ static int test_init_from_config(void)
}
/* Test _Py_InitializeFromConfig() */
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
config.install_signal_handlers = 0;
/* FIXME: test use_environment */
@ -400,7 +404,7 @@ static int test_init_from_config(void)
config.use_hash_seed = 1;
config.hash_seed = 123;
/* dev_mode=1 is tested in test_init_dev_mode() */
/* dev_mode=1 is tested in init_dev_mode() */
putenv("PYTHONFAULTHANDLER=");
config.faulthandler = 1;
@ -432,6 +436,7 @@ static int test_init_from_config(void)
};
config.argv.length = Py_ARRAY_LENGTH(argv);
config.argv.items = argv;
config.parse_argv = 1;
static wchar_t* xoptions[3] = {
L"core_xoption1=3",
@ -481,7 +486,7 @@ static int test_init_from_config(void)
Py_QuietFlag = 0;
config.quiet = 1;
config.configure_c_stdio = 0;
config.configure_c_stdio = 1;
putenv("PYTHONUNBUFFERED=");
Py_UnbufferedStdioFlag = 0;
@ -516,25 +521,26 @@ static int test_init_from_config(void)
}
static int test_init_dont_parse_argv(void)
static int test_init_parse_argv(int parse_argv)
{
_PyInitError err;
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
static wchar_t* argv[] = {
L"-v",
L"./argv0",
L"-E",
L"-c",
L"pass",
L"arg1",
L"-W",
L"arg2",
L"-v",
L"arg3",
};
config.program_name = L"./_testembed";
config.argv.length = Py_ARRAY_LENGTH(argv);
config.argv.items = argv;
config.parse_argv = 0;
config.parse_argv = parse_argv;
err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
@ -546,6 +552,18 @@ static int test_init_dont_parse_argv(void)
}
static int init_parse_argv(void)
{
return test_init_parse_argv(1);
}
static int init_dont_parse_argv(void)
{
return test_init_parse_argv(0);
}
static void test_init_env_putenvs(void)
{
putenv("PYTHONHASHSEED=42");
@ -619,12 +637,13 @@ static int test_init_env_dev_mode_alloc(void)
}
static int test_init_isolated(void)
static int init_isolated_flag(void)
{
_PyInitError err;
/* Test _PyCoreConfig.isolated=1 */
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
Py_IsolatedFlag = 0;
config.isolated = 1;
@ -648,7 +667,8 @@ static int test_preinit_isolated1(void)
{
_PyInitError err;
_PyPreConfig preconfig = _PyPreConfig_INIT;
_PyPreConfig preconfig;
_PyPreConfig_Init(&preconfig);
preconfig.isolated = 1;
err = _Py_PreInitialize(&preconfig);
@ -656,7 +676,8 @@ static int test_preinit_isolated1(void)
_Py_ExitInitError(err);
}
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
config.program_name = L"./_testembed";
test_init_env_dev_mode_putenvs();
@ -675,7 +696,8 @@ static int test_preinit_isolated2(void)
{
_PyInitError err;
_PyPreConfig preconfig = _PyPreConfig_INIT;
_PyPreConfig preconfig;
_PyPreConfig_Init(&preconfig);
preconfig.isolated = 0;
err = _Py_PreInitialize(&preconfig);
@ -684,7 +706,8 @@ static int test_preinit_isolated2(void)
}
/* Test _PyCoreConfig.isolated=1 */
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
Py_IsolatedFlag = 0;
config.isolated = 1;
@ -703,9 +726,72 @@ static int test_preinit_isolated2(void)
}
static int test_init_dev_mode(void)
static int init_isolated_config(void)
{
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyInitError err;
_PyPreConfig preconfig;
_PyPreConfig_InitIsolatedConfig(&preconfig);
err = _Py_PreInitialize(&preconfig);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
_PyPreConfig *rt_preconfig = &_PyRuntime.preconfig;
assert(rt_preconfig->isolated == 1);
assert(rt_preconfig->use_environment == 0);
_PyCoreConfig config;
err = _PyCoreConfig_InitIsolatedConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
config.program_name = L"./_testembed";
err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
dump_config();
Py_Finalize();
return 0;
}
static int init_python_config(void)
{
_PyInitError err;
_PyPreConfig preconfig;
_PyPreConfig_InitPythonConfig(&preconfig);
err = _Py_PreInitialize(&preconfig);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
_PyCoreConfig config;
err = _PyCoreConfig_InitPythonConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
config.program_name = L"./_testembed";
err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
dump_config();
Py_Finalize();
return 0;
}
static int init_dev_mode(void)
{
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
putenv("PYTHONFAULTHANDLER=");
putenv("PYTHONMALLOC=");
config.dev_mode = 1;
@ -723,7 +809,8 @@ static int test_init_dev_mode(void)
static int test_init_read_set(void)
{
_PyInitError err;
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
err = _PyCoreConfig_DecodeLocale(&config.program_name, "./init_read_set");
if (_Py_INIT_FAILED(err)) {
@ -772,13 +859,15 @@ static void configure_init_main(_PyCoreConfig *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";
}
static int test_init_run_main(void)
{
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
configure_init_main(&config);
_PyInitError err = _Py_InitializeFromConfig(&config);
@ -792,7 +881,8 @@ static int test_init_run_main(void)
static int test_init_main(void)
{
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
configure_init_main(&config);
config._init_main = 0;
@ -821,7 +911,8 @@ static int test_init_main(void)
static int test_run_main(void)
{
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
wchar_t *argv[] = {L"python3", L"-c",
(L"import sys; "
@ -829,6 +920,7 @@ static int test_run_main(void)
L"arg2"};
config.argv.length = Py_ARRAY_LENGTH(argv);
config.argv.items = argv;
config.parse_argv = 1;
config.program_name = L"./python3";
_PyInitError err = _Py_InitializeFromConfig(&config);
@ -869,12 +961,15 @@ static struct TestCase TestCases[] = {
{ "init_default_config", test_init_default_config },
{ "init_global_config", test_init_global_config },
{ "init_from_config", test_init_from_config },
{ "init_dont_parse_argv", test_init_dont_parse_argv },
{ "init_parse_argv", init_parse_argv },
{ "init_dont_parse_argv", init_dont_parse_argv },
{ "init_env", test_init_env },
{ "init_env_dev_mode", test_init_env_dev_mode },
{ "init_env_dev_mode_alloc", test_init_env_dev_mode_alloc },
{ "init_dev_mode", test_init_dev_mode },
{ "init_isolated", test_init_isolated },
{ "init_dev_mode", init_dev_mode },
{ "init_isolated_flag", init_isolated_flag },
{ "init_isolated_config", init_isolated_config },
{ "init_python_config", init_python_config },
{ "preinit_isolated1", test_preinit_isolated1 },
{ "preinit_isolated2", test_preinit_isolated2 },
{ "init_read_set", test_init_read_set },

View File

@ -109,7 +109,7 @@ static const char usage_6[] =
/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
stdin and stdout error handler to "surrogateescape". It is equal to
-1 by default: unknown, will be set by Py_Main() */
int Py_UTF8Mode = -1;
int Py_UTF8Mode = 0;
int Py_DebugFlag = 0; /* Needed by parser.c */
int Py_VerboseFlag = 0; /* Needed by import.c */
int Py_QuietFlag = 0; /* Needed by sysmodule.c */
@ -520,6 +520,61 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
}
void
_PyCoreConfig_Init(_PyCoreConfig *config)
{
*config = _PyCoreConfig_INIT;
}
_PyInitError
_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
{
_PyCoreConfig_Init(config);
config->configure_c_stdio = 1;
config->parse_argv = 1;
return _Py_INIT_OK();
}
_PyInitError
_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
{
_PyCoreConfig_Init(config);
/* set to 1 */
config->isolated = 1;
config->site_import = 1;
config->write_bytecode = 1;
config->buffered_stdio = 1;
/* set to 0 */
config->use_environment = 0;
config->dev_mode = 0;
config->install_signal_handlers = 0;
config->use_hash_seed = 0;
config->faulthandler = 0;
config->tracemalloc = 0;
config->bytes_warning = 0;
config->inspect = 0;
config->interactive = 0;
config->optimization_level = 0;
config->parser_debug = 0;
config->verbose = 0;
config->quiet = 0;
config->user_site_directory = 0;
config->configure_c_stdio = 0;
config->pathconfig_warnings = 0;
#ifdef MS_WINDOWS
config->legacy_windows_stdio = 0;
#endif
return _Py_INIT_OK();
}
/* Copy str into *config_str (duplicate the string) */
_PyInitError
_PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str)
@ -2014,17 +2069,20 @@ core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
{
_PyInitError err;
if (config->parse_argv) {
if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
return _Py_INIT_NO_MEMORY();
}
}
_PyPreConfig preconfig = _PyPreConfig_INIT;
_PyPreConfig preconfig;
_PyPreConfig_Init(&preconfig);
if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) {
err = _Py_INIT_NO_MEMORY();
return err;
}
_PyCoreConfig_GetCoreConfig(&preconfig, config);
_PyPreConfig_GetCoreConfig(&preconfig, config);
err = _PyPreCmdline_Read(precmdline, &preconfig);
if (_Py_INIT_FAILED(err)) {
@ -2155,6 +2213,7 @@ _PyInitError
_PyCoreConfig_Read(_PyCoreConfig *config)
{
_PyInitError err;
_PyWstrList orig_argv = _PyWstrList_INIT;
err = _Py_PreInitializeFromCoreConfig(config, NULL);
if (_Py_INIT_FAILED(err)) {
@ -2163,6 +2222,10 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
_PyCoreConfig_GetGlobalConfig(config);
if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) {
return _Py_INIT_NO_MEMORY();
}
_PyPreCmdline precmdline = _PyPreCmdline_INIT;
err = core_read_precmdline(config, &precmdline);
if (_Py_INIT_FAILED(err)) {
@ -2185,10 +2248,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
goto done;
}
/* precmdline.argv is a copy of config.argv which is modified
by config_read_cmdline() */
const _PyWstrList *argv = &precmdline.argv;
if (_Py_SetArgcArgv(argv->length, argv->items) < 0) {
if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
err = _Py_INIT_NO_MEMORY();
goto done;
}
@ -2249,6 +2309,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
err = _Py_INIT_OK();
done:
_PyWstrList_Clear(&orig_argv);
_PyPreCmdline_Clear(&precmdline);
return err;
}

View File

@ -39,7 +39,8 @@ Py_FrozenMain(int argc, char **argv)
}
}
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')

View File

@ -392,7 +392,8 @@ pathconfig_global_init(void)
}
_PyInitError err;
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
err = _PyCoreConfig_Read(&config);
if (_Py_INIT_FAILED(err)) {

View File

@ -260,6 +260,42 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline,
/* --- _PyPreConfig ----------------------------------------------- */
void
_PyPreConfig_Init(_PyPreConfig *config)
{
*config = _PyPreConfig_INIT;
}
void
_PyPreConfig_InitPythonConfig(_PyPreConfig *config)
{
_PyPreConfig_Init(config);
/* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE
environment variables. */
config->coerce_c_locale = -1;
config->coerce_c_locale_warn = -1;
config->utf8_mode = -1;
}
void
_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
{
_PyPreConfig_Init(config);
config->isolated = 1;
config->use_environment = 0;
#ifdef MS_WINDOWS
config->legacy_windows_fs_encoding = 0;
#endif
config->utf8_mode = 0;
config->dev_mode = 0;
}
int
_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
{
@ -346,7 +382,7 @@ fail:
void
_PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
_PyPreConfig_GetCoreConfig(_PyPreConfig *config,
const _PyCoreConfig *core_config)
{
#define COPY_ATTR(ATTR) \
@ -366,11 +402,11 @@ static void
_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
{
#define COPY_FLAG(ATTR, VALUE) \
if (config->ATTR == -1) { \
if (config->ATTR < 0) { \
config->ATTR = VALUE; \
}
#define COPY_NOT_FLAG(ATTR, VALUE) \
if (config->ATTR == -1) { \
if (config->ATTR < 0) { \
config->ATTR = !(VALUE); \
}
@ -379,8 +415,8 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
#ifdef MS_WINDOWS
COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
#endif
if (Py_UTF8Mode > 0) {
config->utf8_mode = 1;
if (config->utf8_mode == -2) {
config->utf8_mode = Py_UTF8Mode;
}
#undef COPY_FLAG
@ -392,11 +428,11 @@ static void
_PyPreConfig_SetGlobalConfig(const _PyPreConfig *config)
{
#define COPY_FLAG(ATTR, VAR) \
if (config->ATTR != -1) { \
if (config->ATTR >= 0) { \
VAR = config->ATTR; \
}
#define COPY_NOT_FLAG(ATTR, VAR) \
if (config->ATTR != -1) { \
if (config->ATTR >= 0) { \
VAR = !config->ATTR; \
}
@ -575,8 +611,10 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
}
}
else if (strcmp(env, "warn") == 0) {
if (config->coerce_c_locale_warn < 0) {
config->coerce_c_locale_warn = 1;
}
}
else {
if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 1;
@ -587,10 +625,7 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
/* Test if coerce_c_locale equals to -1 or equals to 1:
PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced.
It is only coerced if if the LC_CTYPE locale is "C". */
if (config->coerce_c_locale == 0 || config->coerce_c_locale == 2) {
return;
}
if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) {
/* The C locale enables the C locale coercion (PEP 538) */
if (_Py_LegacyLocaleDetected()) {
config->coerce_c_locale = 2;
@ -598,8 +633,11 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
else {
config->coerce_c_locale = 0;
}
}
assert(config->coerce_c_locale >= 0);
if (config->coerce_c_locale_warn < 0) {
config->coerce_c_locale_warn = 0;
}
}
@ -659,6 +697,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
}
assert(config->coerce_c_locale >= 0);
assert(config->coerce_c_locale_warn >= 0);
#ifdef MS_WINDOWS
assert(config->legacy_windows_fs_encoding >= 0);
#endif
@ -700,7 +739,8 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
}
/* Save the config to be able to restore it if encodings change */
_PyPreConfig save_config = _PyPreConfig_INIT;
_PyPreConfig save_config;
_PyPreConfig_Init(&save_config);
if (_PyPreConfig_Copy(&save_config, config) < 0) {
return _Py_INIT_NO_MEMORY();
}

View File

@ -701,7 +701,8 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
return _Py_INIT_OK();
}
_PyPreConfig config = _PyPreConfig_INIT;
_PyPreConfig config;
_PyPreConfig_Init(&config);
if (src_config) {
if (_PyPreConfig_Copy(&config, src_config) < 0) {
@ -752,13 +753,22 @@ _PyInitError
_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
const _PyArgv *args)
{
_PyPreConfig config = _PyPreConfig_INIT;
_PyPreConfig config;
_PyPreConfig_Init(&config);
if (coreconfig != NULL) {
_PyCoreConfig_GetCoreConfig(&config, coreconfig);
_PyPreConfig_GetCoreConfig(&config, coreconfig);
}
if (args == NULL && coreconfig != NULL && coreconfig->parse_argv) {
_PyArgv config_args = {
.use_bytes_argv = 0,
.argc = coreconfig->argv.length,
.wchar_argv = coreconfig->argv.items};
return _Py_PreInitializeFromPyArgv(&config, &config_args);
}
else {
return _Py_PreInitializeFromPyArgv(&config, args);
/* No need to clear config:
_PyCoreConfig_GetCoreConfig() doesn't allocate memory */
}
}
@ -829,7 +839,8 @@ _Py_InitializeCore(_PyRuntimeState *runtime,
return err;
}
_PyCoreConfig local_config = _PyCoreConfig_INIT;
_PyCoreConfig local_config;
_PyCoreConfig_Init(&local_config);
err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p);
_PyCoreConfig_Clear(&local_config);
return err;
@ -1051,7 +1062,8 @@ Py_InitializeEx(int install_sigs)
return;
}
_PyCoreConfig config = _PyCoreConfig_INIT;
_PyCoreConfig config;
_PyCoreConfig_Init(&config);
config.install_signal_handlers = install_sigs;
err = _Py_InitializeFromConfig(&config);

View File

@ -49,7 +49,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
_PyGC_Initialize(&runtime->gc);
_PyEval_Initialize(&runtime->ceval);
runtime->preconfig = _PyPreConfig_INIT;
_PyPreConfig_Init(&runtime->preconfig);
runtime->gilstate.check_enabled = 1;
@ -189,7 +189,7 @@ PyInterpreterState_New(void)
memset(interp, 0, sizeof(*interp));
interp->id_refcount = -1;
interp->check_interval = 100;
interp->core_config = _PyCoreConfig_INIT;
_PyCoreConfig_Init(&interp->core_config);
interp->eval_frame = _PyEval_EvalFrameDefault;
#ifdef HAVE_DLOPEN
#if HAVE_DECL_RTLD_NOW