From 56cf0019a7ba590a2daedc848c42f7dd138f168e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2026 16:32:45 +0200 Subject: [PATCH 1/2] gh-158001: Avoid deprecated variable in Py_GETENV() No longer use deprecated Py_IgnoreEnvironmentFlag in Py_GETENV(). Instead, use PyConfig.use_environment when Python is initialized. --- Lib/test/test_embed.py | 4 ++++ Programs/_testembed.c | 38 ++++++++++++++++++++++++++++++++++++++ Python/initconfig.c | 12 ++++++++---- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 1ff600e30bf4cb..9770fac956e649 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -2114,6 +2114,10 @@ def test_thread_state_ensure_from_view(self): def test_concurrent_finalization_stress(self): self.run_embedded_interpreter("test_concurrent_finalization_stress") + def test_py_getenv(self): + # Test Py_GETENV() before init, when initialized, and after finalize + self.run_embedded_interpreter("test_py_getenv") + class MiscTests(EmbeddingTestsMixin, unittest.TestCase): def test_unicode_id_init(self): diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 418609abc5f6b8..63260c9e5f6cc4 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -2357,6 +2357,43 @@ static int test_isinitialized_false_during_site_import(void) } +static int test_py_getenv(void) +{ + const char *name = "PYTHON_TESTEMBED_VARIABLE"; + const char *expected = "expected_value"; + putenv("PYTHON_TESTEMBED_VARIABLE=expected_value"); + + const char *var = Py_GETENV(name); + if (var == NULL || strcmp(var, expected) != 0) { + error_fmt("%s is not set before Python initialization", name); + return 1; + } + + // Initialize Python with use_environment=0 + PyConfig config; + _PyConfig_InitCompatConfig(&config); + config_set_program_name(&config); + config.use_environment = 0; + init_from_config_clear(&config); + + var = Py_GETENV(name); + if (var != NULL) { + error_fmt("Py_GETENV() doesn't ignore %s after Python init", name); + return 1; + } + + Py_Finalize(); + var = Py_GETENV(name); + if (var == NULL || strcmp(var, expected) != 0) { + error_fmt("%s is not set after Python finalization", name); + return 1; + } + + printf("OK\n"); + return 0; +} + + #ifndef MS_WINDOWS #include "test_frozenmain.h" // M_test_frozenmain @@ -3059,6 +3096,7 @@ static struct TestCase TestCases[] = { {"test_init_main_interpreter_settings", test_init_main_interpreter_settings}, {"test_init_in_background_thread", test_init_in_background_thread}, {"test_isinitialized_false_during_site_import", test_isinitialized_false_during_site_import}, + {"test_py_getenv", test_py_getenv}, // Audit {"test_open_code_hook", test_open_code_hook}, diff --git a/Python/initconfig.c b/Python/initconfig.c index 49f1beb37bb920..ac0845b892903c 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -712,13 +712,17 @@ _Py_COMP_DIAG_POP char* Py_GETENV(const char *name) { -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - if (Py_IgnoreEnvironmentFlag) { + int use_environment = 1; + PyThreadState *tstate = PyThreadState_GetUnchecked(); + if (tstate != NULL) { + const PyConfig *config = &tstate->interp->config; + use_environment = config->use_environment; + } + + if (!use_environment) { return NULL; } return getenv(name); -_Py_COMP_DIAG_POP } /* --- PyStatus ----------------------------------------------- */ From 9480ff30ead2a3c2d6d682d8581ea37160a046a8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Sep 2026 16:45:14 +0200 Subject: [PATCH 2/2] Patch also PySys_SetArgv() Modify also PySys_SetArgv() to use PyConfig.isolated when Python is initialized. --- Python/sysmodule.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 03e5ac7415beb9..b3ec8461485de1 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -4540,9 +4540,16 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) void PySys_SetArgv(int argc, wchar_t **argv) { + int isolated = 0; + PyThreadState *tstate = PyThreadState_GetUnchecked(); + if (tstate != NULL) { + const PyConfig *config = &tstate->interp->config; + isolated = config->isolated; + } + _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS - PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0); + PySys_SetArgvEx(argc, argv, isolated == 0); _Py_COMP_DIAG_POP }