Repository navigation
With LOCALAPPDATA unset, install_dir resolves to the current directory; auto-install then deletes registry entries and shortcuts of the real installs #427
Description
Install source and version
- Installed from the Windows Store
- Installed with the MSIX from python.org
- Installed with the MSI from python.org
- Installed with
winget install 9NQ7512CXL7T
Version: 26.4 (PythonSoftwareFoundation.PythonManager_26.4.240.0_x64), Windows 11 Pro 25H2 (10.0.26200)
Describe the bug
When py is started with an environment that lacks LOCALAPPDATA (e.g. a tool that spawns processes with a minimal environment), the built-in default install_dir = %LocalAppData%\Python resolves to <current directory>\Python. py then sees no runtimes, automatically installs the default runtime into the current directory, and the follow-up registration cleanup removes the PEP 514 registry keys, Start menu shortcuts and ARP entries of the runtimes that are really installed under %LocalAppData%\Python, because they are not visible from the wrong root. It leaves a PythonCore\3.15 key pointing into the arbitrary directory.
To Reproduce
With 3.13 and 3.14 installed normally, from Git Bash (any way of starting a process with only PATH and SYSTEMROOT set reproduces it):
mkdir /tmp/pm-repro && cd /tmp/pm-repro
env -i PATH="$PATH" SYSTEMROOT="$SYSTEMROOT" py list -vv
# Setting config install_dir to C:\Users\<user>\AppData\Local\Temp\pm-repro\Python
# Setting config download_dir to C:\Users\<user>\AppData\Local\Temp\pm-repro\Python\_cache
# Setting config global_dir to C:\Users\<user>\AppData\Local\Temp\pm-repro\Python\bin
env -i PATH="$PATH" SYSTEMROOT="$SYSTEMROOT" py -I -c "print(1)"
Log of the second command (paths shortened):
BEGIN install_command.execute: []
Reading installs from <cwd>\Python
Found 0 installs
> Installing Python 3.15.0.
>> Extracting ...\bundled\pythoncore-3.15-64-3.15.0.zip to <cwd>\Python\pythoncore-3.15-64
Cleaning up registry entries
Skipping HKEY_CURRENT_USER\Software\Python\Astral\CPython3.12.14
Removing HKEY_CURRENT_USER\Software\Python\PythonCore\3.13
Removing HKEY_CURRENT_USER\Software\Python\PythonCore\3.14
Cleaning up Start menu shortcuts
Removing ...\Start Menu\Programs\Python\Python 3.13\...
Removing ...\Start Menu\Programs\Python\Python 3.14\...
Removing ARP registration for pymanager-pythoncore-3.13-64
Removing ARP registration for pymanager-pythoncore-3.14-64
The log file itself was also written to the current directory (presumably because TEMP was unset too). With automatic_install disabled by policy, the second command fails with No runtimes are installed instead, but py list -vv still creates <cwd>\Python\_cache\last_welcome.txt.
Expected behavior
- If
%LocalAppData%cannot be expanded, resolve the folder from the OS (SHGetKnownFolderPath(FOLDERID_LocalAppData)does not depend on environment variables), or fail with a clear error. It should not silently fall back to the current directory. - The registry/shortcut/ARP cleanup should not remove entries for runtimes it cannot see because its root changed. Only removing keys whose
InstallPathlies under the currentinstall_dir(or whose target no longer exists) would make this safe.
Additional context
py install --refreshrun with the normal environment restored the registry, shortcuts and ARP entries.- Workaround in use: an
HKLM\Software\Policies\Python\PyManagerbase_configpointing to a JSON file with absoluteinstall_dir,download_dir,global_dir,logs_diranduser_config. With it, the sameenv -i ... py -I -ccommand runs the installed 3.14 normally and touches nothing. user_config(%AppData%\Python\PyManager.json) has the same fallback: withoutAPPDATAit resolves to<cwd>\Python\PyManager.json, and a file there would replace the configured paths.- Possibly related: Please support fully managed Python runtimes at explicitly selected drive/path locations #423 (explicit install locations), but that issue does not cover this failure mode.
Activity
zooba commentedon Oct 13, 2026
We can probably make the config loader warn about empty environment variables in cases where there's string concatenation involved, and define 1-2 fallback lookups.
A process environment missing standard variables like these is essentially corrupted, from our POV, so there's no security angle here (just noting it explicitly - if this had been reported as a security issue it would be immediately made public on that basis).
The "explicitly selected location" feature request is entirely unrelated.
zooba commentedon Oct 13, 2026
For reference, this is the function that needs enhancing to handle missing environment variables:
pymanager/src/manage/config.py
Lines 153 to 161 in 3f6af8d