mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
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:
parent
b16b4e4592
commit
cab5d0741e
12 changed files with 362 additions and 91 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue