More resilient registry removal (#14717)

With the previous order of operations, there could be warnings from race
conditions between two process A and B removing and installing Python
versions.

* A removes the files for CPython3.9.18
* B sees the key CPython3.9.18
* B sees that CPython3.9.18 has no files
* A removes the key for CPython3.9.18
* B try to removes the key for CPython3.9.18, gets and error that it's
already gone, issues a warning

We make the more resilient in two ways:

* We remove the registry key first, avoiding dangling registry keys in
the removal process
* We ignore not found errors in registry removal operations: If we try
to remove something that's already gone, that's fine.

Fixes #14714 (hopefully)
This commit is contained in:
konsti 2025-07-18 14:47:56 +02:00 committed by GitHub
parent 8f2f43c561
commit d1f4f8a358
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 11 deletions

View file

@ -268,6 +268,9 @@ pub fn remove_orphan_registry_entries(installations: &[ManagedPythonInstallation
// Separate assignment since `keys()` creates a borrow.
let subkeys = match key.keys() {
Ok(subkeys) => subkeys,
Err(err) if err.code() == ERROR_NOT_FOUND => {
return;
}
Err(err) => {
// TODO(konsti): We don't have an installation key here.
warn_user_once!("Failed to list subkeys of HKCU:\\{astral_key}: {err}");
@ -281,6 +284,9 @@ pub fn remove_orphan_registry_entries(installations: &[ManagedPythonInstallation
let python_entry = format!("{astral_key}\\{subkey}");
debug!("Removing orphan registry key HKCU:\\{}", python_entry);
if let Err(err) = CURRENT_USER.remove_tree(&python_entry) {
if err.code() == ERROR_NOT_FOUND {
continue;
}
// TODO(konsti): We don't have an installation key here.
warn_user_once!("Failed to remove orphan registry key HKCU:\\{python_entry}: {err}");
}