New submission from Eryk Sun <[email protected]>:
In 3.7.2 on Windows, venv now uses a redirecting launcher 'script' for
python[w].exe. This replaces (on Windows only) the setup requirement to copy or
symlink the interpreter binaries (i.e. python[w].exe, python37.dll, and
vcruntime140.dll). Apparently this is required to be able to install Python as
a Windows Store app. I haven't experimented with it yet, so I'll just accept
that as a given. I'm curious to find out whether using symlinks would still
work, and even if it doesn't work for the app installation, whether we could
still support that option for desktop installations. I've used `--symlinks` for
a while now, since I grant the required privilege to the authenticated users
group and thus don't have to elevate to create symlinks. (I know it's not so
easy for many Windows users.)
The new launcher reads pyvenv.cfg to locate and execute the real python.exe.
Since the process image is no longer in the virtual environment's "Scripts"
directory (which has various consequences), we need a way to communicate the
launcher's path to make Python use the virtual environment. A -X command-line
option could work, but then all packages and tools that spawn worker processes,
such as multiprocessing, would need to be updated to look for this option in
sys._xoptions and propagate it. Instead the launcher sets a special
"__PYVENV_LAUNCHER__" environment variable. This is reasonable because
processes are usually created with a copy of the parent's environment. Some
environment variables may be added or modified, but it's rare for a child
process to get a completely new environment. (One example of the latter would
be creating a process that runs as a different user.)
An oversight in the current ecosystem is that py.exe and the distlib
entry-point launchers do not unset "__PYVENV_LAUNCHER__". Thus, when executing
a script from a virtual environment (e.g. either directly via py.exe or via the
.py file association), it will mistakenly be pinned into the virtual
environment if it runs in Python 3.7. Similarly, pip.exe for an installed
Python 3.7 will mistakenly install into the virtual environment. However, the
latter is out of scope here since the entry-point launchers are in distlib.
It's also a problem if we run the fully-qualified path for an installed Python
3.7, e.g. from shutil.which('python'). We can't automatically address this
since it's exactly the reason "__PYVENV_LAUNCHER__" exists. We have to know to
manually unset "__PYVENV_LAUNCHER__" in the environment that's passed to the
child. This should be documented somewhere -- maybe in the venv docs.
It's not a problem if a script runs unqualified "python.exe" since the final
result is usually the same, but for different reasons. With the launcher, it's
locked down by inheriting "__PYVENV_LAUNCHER__". With the previous design, the
application directory was the virtual environment's "Scripts" directory.
Unqualified "python.exe" was thus pinned for CreateProcessW, which checks the
application directory first. It's also not a problem if we run sys.executable,
since previously that was the virtual environment's executable. (In 3.7.2,
sys.executable gets set to the virtual environment's launcher, but that breaks
multiprocessing. See issue 35797.)
----------
components: Windows
messages: 334275
nosy: eryksun, paul.moore, steve.dower, tim.golden, vinay.sajip, zach.ware
priority: normal
severity: normal
stage: test needed
status: open
title: py.exe should unset the __PYVENV_LAUNCHER__ environment variable
type: behavior
versions: Python 3.7, Python 3.8
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue35811>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com