sys.base_prefix
locates the standard library of the base Python installation, not the base executable, or at least not the preferred base executable. Fortunately, CPython in Windows sets a value that should be what you want: sys._base_executable
. For example:
>>> local_appdata = os.environ['LocalAppData']
>>> print(f'{sys._base_executable.replace(local_appdata, "%LocalAppData%")}')
%LocalAppData%\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\python.exe
sys._base_executable
is used by multiprocessing, and anything else that needs to bypass the virtual environment’s launcher when spawning a worker process. It’s based on the “__PYVENV_LAUNCHER__” environment variable that the launcher sets.
For the 3.9 store app, the canonically-named, real executable is “%ProgramFiles%\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\python3.9.exe”. You should be able to directly execute this file, as well as “pythonw3.9.exe”, “pip3.9.exe”, and “idle3.9.exe” beside it. For example:
C:\>"%ProgramFiles%\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\python3.9.exe" -V
Python 3.9.13
On the other hand, “%ProgramFiles%\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\python.exe” can’t be executed directly from the shell. It could be if it were a symlink to “python3.9.exe” [1], but as installed it’s just a regular file, not a symlink. It can only be executed either from within the Python 3.9 app itself (e.g. via subprocess.run()
) or by running the “python.exe” appexec link (alias) in “%LocalAppData%\Microsoft\WindowsApps”.
If the alias is disabled in the app settings, the appexec link is still available in its package subdirectory, e.g. “%LocalAppData%\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\python.exe”. This appexec link is the most generally available and accessible path for the executable, so it’s what gets used for sys.executable
in the normal environment, and for sys._base_executable
in a virtual environment.
[1] I tested this in Windows 11 by deleting the existing “python.exe” and manually creating “python.exe” as a symlink to “python3.9.exe”. It’s not trivial to create a symlink in a subdirectory of “%ProgramFiles%\WindowsApps”. Here’s a high-level overview. As an administrator or SYSTEM, enable SeBackupPrivilege and SeRestorePrivilege via OpenProcessToken()
and AdjustTokenPrivileges()
. Call CreateFileW()
with the flag FILE_FLAG_BACKUP_SEMANTICS
to create “python.exe”. Call DeviceIoControl()
to set the IO_REPARSE_TAG_SYMLINK
reparse point that targets “python3.9.exe”.