https://github.com/python/cpython/commit/2f5791df35c66cf5f300d82d86dd6854c71d12bc
commit: 2f5791df35c66cf5f300d82d86dd6854c71d12bc
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-23T21:21:38+02:00
summary:

gh-158001: No longer read global config vars in PyConfig_Read() (#158014)

PyConfig_Read() and _PyPreConfig_Read() no longer read global config
variables (such as Py_BytesWarningFlag). Instead, PyConfig_Read() now
copies PyPreConfig members (isolated, use_environment and dev_mode).

_PyPreConfig_Read() still reads the last global configuration
variable: Py_UTF8Mode.

files:
M Lib/test/test_embed.py
M Programs/_testembed.c
M Python/initconfig.c
M Python/preconfig.c

diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 9770fac956e649..81241ea1f33733 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -1095,24 +1095,11 @@ def test_init_compat_config(self):
         self.check_all_configs("test_init_compat_config", api=API_COMPAT)
 
     def test_init_global_config(self):
+        # Test Py_UTF8Mode global configuration variable
         preconfig = {
             'utf8_mode': True,
         }
-        config = {
-            'site_import': False,
-            'bytes_warning': True,
-            'warnoptions': ['default::BytesWarning'],
-            'inspect': True,
-            'interactive': True,
-            'optimization_level': 2,
-            'write_bytecode': False,
-            'verbose': True,
-            'quiet': True,
-            'buffered_stdio': False,
-            'remote_debug': True,
-            'user_site_directory': False,
-            'pathconfig_warnings': False,
-        }
+        config = {}
         self.check_all_configs("test_init_global_config", config, preconfig,
                                api=API_COMPAT)
 
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 63260c9e5f6cc4..17b93ba47caac4 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -597,43 +597,9 @@ static int test_init_compat_config(void)
 
 static int test_init_global_config(void)
 {
-    /* FIXME: test Py_IgnoreEnvironmentFlag */
-
     putenv("PYTHONUTF8=0");
     Py_UTF8Mode = 1;
 
-    /* Py_IsolatedFlag is not tested */
-    Py_NoSiteFlag = 1;
-    Py_BytesWarningFlag = 1;
-
-    putenv("PYTHONINSPECT=");
-    Py_InspectFlag = 1;
-
-    putenv("PYTHONOPTIMIZE=0");
-    Py_InteractiveFlag = 1;
-
-    putenv("PYTHONDEBUG=0");
-    Py_OptimizeFlag = 2;
-
-    /* Py_DebugFlag is not tested */
-
-    putenv("PYTHONDONTWRITEBYTECODE=");
-    Py_DontWriteBytecodeFlag = 1;
-
-    putenv("PYTHONVERBOSE=0");
-    Py_VerboseFlag = 1;
-
-    Py_QuietFlag = 1;
-    Py_NoUserSiteDirectory = 1;
-
-    putenv("PYTHONUNBUFFERED=");
-    Py_UnbufferedStdioFlag = 1;
-
-    Py_FrozenFlag = 1;
-
-    /* FIXME: test Py_LegacyWindowsFSEncodingFlag */
-    /* FIXME: test Py_LegacyWindowsStdioFlag */
-
     _testembed_initialize();
     dump_config();
     Py_Finalize();
@@ -734,39 +700,30 @@ static int test_init_from_config(void)
     config_set_string(&config, &config.platlibdir, L"my_platlibdir");
 
     putenv("PYTHONVERBOSE=0");
-    Py_VerboseFlag = 0;
     config.verbose = 1;
 
-    Py_NoSiteFlag = 0;
     config.site_import = 0;
 
-    Py_BytesWarningFlag = 0;
     config.bytes_warning = 1;
 
     putenv("PYTHONINSPECT=");
-    Py_InspectFlag = 0;
     config.inspect = 1;
 
-    Py_InteractiveFlag = 0;
     config.interactive = 1;
 
     putenv("PYTHONOPTIMIZE=0");
-    Py_OptimizeFlag = 1;
     config.optimization_level = 2;
 
     /* FIXME: test parser_debug */
 
     putenv("PYTHONDONTWRITEBYTECODE=");
-    Py_DontWriteBytecodeFlag = 0;
     config.write_bytecode = 0;
 
-    Py_QuietFlag = 0;
     config.quiet = 1;
 
     config.configure_c_stdio = 1;
 
     putenv("PYTHONUNBUFFERED=");
-    Py_UnbufferedStdioFlag = 0;
     config.buffered_stdio = 0;
 
     putenv("PYTHONIOENCODING=cp424");
@@ -774,12 +731,10 @@ static int test_init_from_config(void)
     config_set_string(&config, &config.stdio_errors, L"replace");
 
     putenv("PYTHONNOUSERSITE=");
-    Py_NoUserSiteDirectory = 0;
     config.user_site_directory = 0;
 
     config_set_string(&config, &config.check_hash_pycs_mode, L"always");
 
-    Py_FrozenFlag = 0;
     config.pathconfig_warnings = 0;
 
     config.safe_path = 1;
@@ -882,7 +837,6 @@ static void set_all_env_vars(void)
 static int test_init_compat_env(void)
 {
     /* Test initialization from environment variables */
-    Py_IgnoreEnvironmentFlag = 0;
     set_all_env_vars();
     _testembed_initialize();
     dump_config();
@@ -918,7 +872,6 @@ static void set_all_env_vars_dev_mode(void)
 static int test_init_env_dev_mode(void)
 {
     /* Test initialization from environment variables */
-    Py_IgnoreEnvironmentFlag = 0;
     set_all_env_vars_dev_mode();
     _testembed_initialize();
     dump_config();
@@ -930,7 +883,6 @@ static int test_init_env_dev_mode(void)
 static int test_init_env_dev_mode_alloc(void)
 {
     /* Test initialization from environment variables */
-    Py_IgnoreEnvironmentFlag = 0;
     set_all_env_vars_dev_mode();
 #ifndef Py_GIL_DISABLED
     putenv("PYTHONMALLOC=malloc");
@@ -950,7 +902,6 @@ static int test_init_isolated_flag(void)
     PyConfig config;
     PyConfig_InitPythonConfig(&config);
 
-    Py_IsolatedFlag = 0;
     config.isolated = 1;
     // These options are set to 1 by isolated=1
     config.safe_path = 0;
@@ -1010,7 +961,6 @@ static int test_preinit_isolated2(void)
     PyConfig config;
     _PyConfig_InitCompatConfig(&config);
 
-    Py_IsolatedFlag = 0;
     config.isolated = 1;
 
     config_set_program_name(&config);
@@ -1081,28 +1031,6 @@ static int test_preinit_parse_argv(void)
 
 
 
-static void set_all_global_config_variables(void)
-{
-    Py_IsolatedFlag = 0;
-    Py_IgnoreEnvironmentFlag = 0;
-    Py_BytesWarningFlag = 2;
-    Py_InspectFlag = 1;
-    Py_InteractiveFlag = 1;
-    Py_OptimizeFlag = 1;
-    Py_DebugFlag = 1;
-    Py_VerboseFlag = 1;
-    Py_QuietFlag = 1;
-    Py_FrozenFlag = 0;
-    Py_UnbufferedStdioFlag = 1;
-    Py_NoSiteFlag = 1;
-    Py_DontWriteBytecodeFlag = 1;
-    Py_NoUserSiteDirectory = 1;
-#ifdef MS_WINDOWS
-    Py_LegacyWindowsStdioFlag = 1;
-#endif
-}
-
-
 static int check_preinit_isolated_config(int preinit)
 {
     PyStatus status;
@@ -1111,9 +1039,6 @@ static int check_preinit_isolated_config(int preinit)
     /* environment variables must be ignored */
     set_all_env_vars();
 
-    /* global configuration variables must be ignored */
-    set_all_global_config_variables();
-
     if (preinit) {
         PyPreConfig preconfig;
         PyPreConfig_InitIsolatedConfig(&preconfig);
@@ -1158,19 +1083,6 @@ static int test_init_isolated_config(void)
 
 static int check_init_python_config(int preinit)
 {
-    /* global configuration variables must be ignored */
-    set_all_global_config_variables();
-    Py_IsolatedFlag = 1;
-    Py_IgnoreEnvironmentFlag = 1;
-    Py_FrozenFlag = 1;
-    Py_UnbufferedStdioFlag = 1;
-    Py_NoSiteFlag = 1;
-    Py_DontWriteBytecodeFlag = 1;
-    Py_NoUserSiteDirectory = 1;
-#ifdef MS_WINDOWS
-    Py_LegacyWindowsStdioFlag = 1;
-#endif
-
     if (preinit) {
         PyPreConfig preconfig;
         PyPreConfig_InitPythonConfig(&preconfig);
@@ -1276,7 +1188,6 @@ static int test_open_code_hook(void)
         return 2;
     }
 
-    Py_IgnoreEnvironmentFlag = 0;
     _testembed_initialize();
     result = 0;
 
@@ -1339,7 +1250,6 @@ static int _test_audit(Py_ssize_t setValue)
 {
     Py_ssize_t sawSet = 0;
 
-    Py_IgnoreEnvironmentFlag = 0;
     PySys_AddAuditHook(_audit_hook, &sawSet);
     _testembed_initialize();
 
@@ -1451,7 +1361,6 @@ static int _audit_subinterpreter_hook(const char *event, 
PyObject *args, void *u
 
 static int test_audit_subinterpreter(void)
 {
-    Py_IgnoreEnvironmentFlag = 0;
     PySys_AddAuditHook(_audit_subinterpreter_hook, NULL);
     _testembed_initialize();
 
@@ -1501,7 +1410,6 @@ static int test_audit_run_command(void)
     AuditRunCommandTest test = {"cpython.run_command"};
     wchar_t *argv[] = {PROGRAM_NAME, L"-c", L"pass"};
 
-    Py_IgnoreEnvironmentFlag = 0;
     PySys_AddAuditHook(_audit_hook_run, (void*)&test);
 
     return Py_Main(Py_ARRAY_LENGTH(argv), argv);
@@ -1512,7 +1420,6 @@ static int test_audit_run_file(void)
     AuditRunCommandTest test = {"cpython.run_file"};
     wchar_t *argv[] = {PROGRAM_NAME, L"filename.py"};
 
-    Py_IgnoreEnvironmentFlag = 0;
     PySys_AddAuditHook(_audit_hook_run, (void*)&test);
 
     return Py_Main(Py_ARRAY_LENGTH(argv), argv);
diff --git a/Python/initconfig.c b/Python/initconfig.c
index ac0845b892903c..464c76f9e3df2f 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -1818,31 +1818,19 @@ config_get_env_dup(PyConfig *config,
 
 
 static void
-config_get_global_vars(PyConfig *config)
+config_read_preconfig(PyConfig *config)
 {
-    if (config->_config_init != _PyConfig_INIT_COMPAT) {
-        /* Python and Isolated configuration ignore global variables */
-        return;
-    }
-
-    const PyConfigSpec *spec = PYCONFIG_SPEC;
-    for (; spec->name != NULL; spec++) {
-        if (spec->global_var.ptr == NULL) {
-            continue;
-        }
-        assert(spec->type == PyConfig_MEMBER_INT
-               || spec->type == PyConfig_MEMBER_UINT
-               || spec->type == PyConfig_MEMBER_BOOL);
-        int *member = config_get_spec_member(config, spec);
-        if (*member != -1) {
-            continue;
-        }
-        int value = *spec->global_var.ptr;
-        if (spec->global_var.not) {
-            value = !value;
+#define COPY_FLAG(ATTR) \
+        if (config->ATTR == -1) { \
+            config->ATTR = preconfig->ATTR; \
         }
-        *member = value;
-    }
+
+    const PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    COPY_FLAG(isolated);
+    COPY_FLAG(use_environment);
+    COPY_FLAG(dev_mode);
+
+#undef COPY_FLAG
 }
 
 
@@ -3748,7 +3736,56 @@ _PyConfig_Read(PyConfig *config, int compute_path_config)
         return status;
     }
 
-    config_get_global_vars(config);
+    config_read_preconfig(config);
+
+    // Set default values
+    if (config->bytes_warning < 0) {
+        config->bytes_warning = 0;
+    }
+    if (config->inspect < 0) {
+        config->inspect = 0;
+    }
+    if (config->interactive < 0) {
+        config->interactive = 0;
+    }
+    if (config->optimization_level < 0) {
+        config->optimization_level = 0;
+    }
+    if (config->parser_debug < 0) {
+        config->parser_debug = 0;
+    }
+    if (config->quiet < 0) {
+        config->quiet = 0;
+    }
+    if (config->use_environment < 0) {
+        config->use_environment = 0;
+    }
+    if (config->verbose < 0) {
+        config->verbose = 0;
+    }
+    if (config->write_bytecode < 0) {
+        config->write_bytecode = 1;
+    }
+    if (config->buffered_stdio < 0) {
+        config->buffered_stdio = 1;
+    }
+    if (config->isolated < 0) {
+        config->isolated = 0;
+    }
+#ifdef MS_WINDOWS
+    if (config->legacy_windows_stdio < 0) {
+        config->legacy_windows_stdio = 0;
+    }
+#endif
+    if (config->pathconfig_warnings < 0) {
+        config->pathconfig_warnings = 1;
+    }
+    if (config->site_import < 0) {
+        config->site_import = 1;
+    }
+    if (config->user_site_directory < 0) {
+        config->user_site_directory = 1;
+    }
 
 #ifdef __CYGWIN__
     status = config_argv0_add_exe(config);
diff --git a/Python/preconfig.c b/Python/preconfig.c
index 2c8c18284c1d2d..16594e545abaed 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -463,36 +463,19 @@ _PyPreConfig_GetConfig(PyPreConfig *preconfig, const 
PyConfig *config)
 
 
 static void
-preconfig_get_global_vars(PyPreConfig *config)
+preconfig_get_global_var(PyPreConfig *config)
 {
     if (config->_config_init != _PyConfig_INIT_COMPAT) {
         /* Python and Isolated configuration ignore global variables */
         return;
     }
 
-#define COPY_FLAG(ATTR, VALUE) \
-    if (config->ATTR < 0) { \
-        config->ATTR = VALUE; \
-    }
-#define COPY_NOT_FLAG(ATTR, VALUE) \
-    if (config->ATTR < 0) { \
-        config->ATTR = !(VALUE); \
-    }
-
 _Py_COMP_DIAG_PUSH
 _Py_COMP_DIAG_IGNORE_DEPR_DECLS
-    COPY_FLAG(isolated, Py_IsolatedFlag);
-    COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
     if (Py_UTF8Mode > 0) {
         config->utf8_mode = Py_UTF8Mode;
     }
-#ifdef MS_WINDOWS
-    COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
-#endif
 _Py_COMP_DIAG_POP
-
-#undef COPY_FLAG
-#undef COPY_NOT_FLAG
 }
 
 
@@ -776,7 +759,7 @@ preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline)
 
    - command line arguments
    - environment variables
-   - Py_xxx global configuration variables
+   - Py_UTF8Mode global configuration variable
    - the LC_CTYPE locale */
 PyStatus
 _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
@@ -788,7 +771,18 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
         return status;
     }
 
-    preconfig_get_global_vars(config);
+    preconfig_get_global_var(config);
+    if (config->use_environment < 0) {
+        config->use_environment = 1;
+    }
+    if (config->isolated < 0) {
+        config->isolated = 0;
+    }
+#ifdef MS_WINDOWS
+    if (config->legacy_windows_fs_encoding < 0) {
+        config->legacy_windows_fs_encoding = 0;
+    }
+#endif
 
     /* Copy LC_CTYPE locale, since it's modified later */
     const char *loc = setlocale(LC_CTYPE, NULL);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to