diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-05-17 17:01:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-17 17:01:14 (GMT) |
commit | cab5d0741ee6adf2ae9ff5aaafe06b75b4b5bca3 (patch) | |
tree | 745b2e08f4a035ffb345e695216934b1a3b6ccda /Python | |
parent | b16b4e45923f4e4dfd8e970ae4e6a934faf73b79 (diff) | |
download | cpython-cab5d0741ee6adf2ae9ff5aaafe06b75b4b5bca3.zip cpython-cab5d0741ee6adf2ae9ff5aaafe06b75b4b5bca3.tar.gz cpython-cab5d0741ee6adf2ae9ff5aaafe06b75b4b5bca3.tar.bz2 |
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
Diffstat (limited to 'Python')
-rw-r--r-- | Python/coreconfig.c | 79 | ||||
-rw-r--r-- | Python/frozenmain.c | 3 | ||||
-rw-r--r-- | Python/pathconfig.c | 3 | ||||
-rw-r--r-- | Python/preconfig.c | 78 | ||||
-rw-r--r-- | Python/pylifecycle.c | 28 | ||||
-rw-r--r-- | Python/pystate.c | 4 |
6 files changed, 155 insertions, 40 deletions
diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 634891e..2e8f4cf 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -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 (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) { - return _Py_INIT_NO_MEMORY(); + 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; } diff --git a/Python/frozenmain.c b/Python/frozenmain.c index f2499ef..0175e42 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -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') diff --git a/Python/pathconfig.c b/Python/pathconfig.c index 2fcb816..c8c69eb 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -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)) { diff --git a/Python/preconfig.c b/Python/preconfig.c index 2bbf8e6..7814ee0 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -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,7 +611,9 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config) } } else if (strcmp(env, "warn") == 0) { - config->coerce_c_locale_warn = 1; + if (config->coerce_c_locale_warn < 0) { + config->coerce_c_locale_warn = 1; + } } else { if (config->coerce_c_locale < 0) { @@ -587,19 +625,19 @@ 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; + } + else { + config->coerce_c_locale = 0; + } } - /* The C locale enables the C locale coercion (PEP 538) */ - if (_Py_LegacyLocaleDetected()) { - config->coerce_c_locale = 2; + if (config->coerce_c_locale_warn < 0) { + config->coerce_c_locale_warn = 0; } - else { - config->coerce_c_locale = 0; - } - - assert(config->coerce_c_locale >= 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(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index eecb439..231706d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -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); } - 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); diff --git a/Python/pystate.c b/Python/pystate.c index 8c906ce..2f80aa2 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -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 |