Prevent sys.prefix from leaking into child process on macOS #1648
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #1643
This PR fixes a bug on macOS where virtualenv, when run inside a virtual environment, identifies every Python interpreter as the interpreter used to generate the virtual environment.
There is a related upstream bug at bpo22490, with an open PR at python/cpython#9516.
Setup
~/Library/Application\ Support/virtualenv/
./usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/bin/python3.7
(via Homebrew)(This is usually accessed as
/usr/local/opt/python/bin/python3.7
.)~/.pyenv/versions/3.8.1/bin/python3.8
(via pyenv)Repro
Step 3 fails with the following error message:
Analysis
Here is a step-by-step analysis.
/tmp/venv/bin/virtualenv -p python3.8 /tmp/venv-3.8
./tmp/venv/bin/python
, a symlink to the framework build of Python 3.7./tmp/venv/bin/python
) in the environment variable__PYVENV_LAUNCHER__
.~/.pyenv/shims/python3.8 /tmp/venv/lib/.../virtualenv/discovery/py_info.py
to obtain information about the interpreter.~/.pyenv/versions/3.8.1/bin/python3.8
(via~/.pyenv/libexec/pyenv-exec
).~/.pyenv/versions/3.8.1/lib/python3.8/site.py
during initialization.site.py
script sees that the platform isdarwin
and the__PYVENV_LAUNCHER__
environment variable is set. It setssys._base_executable
to the value of__PYVENV_LAUNCHER__
, andsys.prefix
to the grand-parent directory of this path.sys.prefix
is now/tmp/venv
, whilesys.base_prefix
still points to the previous value ofsys.prefix
,~/.pyenv/versions/3.8.1
.sys.prefix
andsys.base_prefix
differ, and assumes that the interpreter is running in a virtual environment. It determines the system executable usingsys._base_executable
,/tmp/venv/bin/python
./tmp/venv/bin/python
to identify the interpreter, overriding the information previously gathered from the pyenv-provided Python 3.8. The interpreter is identified as Python 3.7.References to source code:
Step 7:
https://github.com/python/cpython/blob/d4d17fd2cf69e7c8f4cd03fbf2d575370945b952/Lib/site.py#L460-L461
Step 8:
virtualenv/src/virtualenv/discovery/py_info.py
Lines 94 to 107 in 5b88149
Step 9:
virtualenv/src/virtualenv/discovery/py_info.py
Lines 284 to 294 in 5b88149
virtualenv/src/virtualenv/discovery/py_info.py
Lines 309 to 326 in 5b88149
Thanks for contributing a pull request, see checklist all is good!
docs/changelog
folder