gh-122941: Fix test_launcher sporadic failures via py.ini isolation (GH-145090)

Adds _PYLAUNCHER_INIDIR as a private variable since the launcher is deprecated and not getting new features.
This commit is contained in:
Itamar Oren 2026-03-04 10:06:49 -08:00 committed by GitHub
parent a00392349c
commit 6cdbd7bc5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 5 deletions

View file

@ -227,6 +227,8 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non
"PYLAUNCHER_LIMIT_TO_COMPANY": "",
**{k.upper(): v for k, v in (env or {}).items()},
}
if ini_dir := getattr(self, '_ini_dir', None):
env.setdefault("_PYLAUNCHER_INIDIR", ini_dir)
if not argv:
argv = [self.py_exe, *args]
with subprocess.Popen(
@ -262,11 +264,14 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non
return data
def py_ini(self, content):
local_appdata = os.environ.get("LOCALAPPDATA")
if not local_appdata:
raise unittest.SkipTest("LOCALAPPDATA environment variable is "
"missing or empty")
return PreservePyIni(Path(local_appdata) / "py.ini", content)
ini_dir = getattr(self, '_ini_dir', None)
if not ini_dir:
local_appdata = os.environ.get("LOCALAPPDATA")
if not local_appdata:
raise unittest.SkipTest("LOCALAPPDATA environment variable is "
"missing or empty")
ini_dir = local_appdata
return PreservePyIni(Path(ini_dir) / "py.ini", content)
@contextlib.contextmanager
def script(self, content, encoding="utf-8"):
@ -302,6 +307,8 @@ def setUpClass(cls):
p = subprocess.check_output("reg query HKCU\\Software\\Python /s")
#print(p.decode('mbcs'))
cls._ini_dir = tempfile.mkdtemp()
cls.addClassCleanup(shutil.rmtree, cls._ini_dir, ignore_errors=True)
@classmethod
def tearDownClass(cls):

View file

@ -922,6 +922,20 @@ _readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, in
{
wchar_t iniPath[MAXLEN];
int n;
// Check for _PYLAUNCHER_INIDIR override (used for test isolation)
DWORD len = GetEnvironmentVariableW(L"_PYLAUNCHER_INIDIR", iniPath, MAXLEN);
if (len && len < MAXLEN) {
if (join(iniPath, MAXLEN, L"py.ini")) {
debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName);
n = GetPrivateProfileStringW(section, settingName, NULL, buffer, bufferLength, iniPath);
if (n) {
debug(L"# Found %s in %s\n", settingName, iniPath);
return n;
}
}
// When _PYLAUNCHER_INIDIR is set, skip the default locations
return 0;
}
if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, iniPath)) &&
join(iniPath, MAXLEN, L"py.ini")) {
debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName);