Find python executable used for venv creation

Hello,

usually one can find the python executable, that was used for creation of the current venv, by looking into the path returned by sys.base_prefix (directly in the root folder or in some subfolder).

If Python was installed via Microsoft Store, sys.base_prefix will return something like C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0. This folder indeed contains a python.exe, but calling this within a subprocess results in an Access Denied.

The intended base folder seems to be `C:\Users\{username}\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0``. Is there a reliable way to find that location or do I have to make some kind of educated guess?

fin swimmer

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”.