I\'m using Python 3.4, and having created a pyvenv, I\'m looking to activate it from within a python process. With virtualenv, I used to use activate_this.py, b
pyvenv and the venv module don't support this out of the box. The third party virtualenv package does support this using activate_this.py, but that feature was not included in the built-in venv module.
You could try to borrow a copy of activate_this.py from a virtualenv based environment; it seems to work, though I can't swear it will be perfect (venv/pyvenv uses some magic during startup; unclear if all of it is replicated via activate_this.py).
The virtualenv docs for it are out of date for Python 3 (they claim you use execfile, which doesn't exist). The Python 3 compatible alternative would be:
activator = 'some/path/to/activate_this.py' # Looted from virtualenv; should not require modification, since it's defined relatively
with open(activator) as f:
exec(f.read(), {'__file__': activator})
Nothing activate_this.py does is magical, so you could manually perform the same changes without looting from virtualenv (adjusting PATH, sys.path, sys.prefix, etc.), but borrowing makes it much simpler in this case.
import argparse
import base64
import os
import zlib
from pathlib import Path
def convert(s):
b = base64.b64decode(s.encode('ascii'))
return zlib.decompress(b).decode('utf-8')
ACTIVATE_THIS = convert("""
eJyNU01v2zAMvetXEB4K21jnDOstQA4dMGCHbeihlyEIDMWmE62yJEiKE//7kXKdpEWLzYBt8evx
kRSzLPs6wiEoswM8YdMpjUXcq1Dz6RZa1cSiTkJdr86GsoTRHuCotBayiWqQEYGtMCgfD1KjGYBe
5a3p0cRKiEe2NtLAFikftnDco0ko/SFEVgEZ8aRCZDIPY9xbA8pE9M4jfW/B2CjiHq9zbJVZuOQq
siwTIvpxKYCembPAU4Muwi/Z4zfvrZ/MXipKeB8C+qisSZYiWfjJfs+0/MFMdWn1hJcO5U7G/SLa
xVx8zU6VG/PXLXvfsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCJN9dzKaoexyB/uH79TnjwvxcW0ntSb
yZ8jq1Z5Q1UXsyy3gf9nbjTEj7NzQMfCJa/YSmrQ+2D/BqfiOi6sclrGzvoeVivIj8rcfcmnIQRF
7XCyeZI7DFe5/lhlCs5PRf5QW66VXT/NrlQ46oD/D6InkOmi3IQcbhKxAX2g4a+Xd5s3UtCtG2py
m8eg6WYWqR6SL5OjKMGfSrYt/6kxxQtOpeAgj1LXBNmpE2ElmCSIy5H0zFd8gJ924HWijWhb2hRC
6wNEm1QdDZtuSZcEprIUBo/XRNcbQe1OUbQ/r3hPTaPJJDNtFLu8KHV5XoNr3Eo6h6YtOKw8e8yw
VF5PnJ+ts3a9/Mz38RpG/AUSzYUW
""")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--virtualenv-dir', default=os.environ['VIRTUAL_ENV'])
args = parser.parse_args()
activate_this_path = Path(args.virtualenv_dir) / 'bin/activate_this.py'
print(f'Writing activate_this.py to {activate_this_path}')
with open(activate_this_path, 'w') as fp:
fp.write(ACTIVATE_THIS)
I took this from the virtualenv project itself. here search for ACTIVATE_THIS
The script will write an activate_this.py to your virtual environment bin.
With poetry you can do:
poetry run python venv_activate_this.py
For python venv do:
source venv/bin/activate
python venv_activate_this.py
And from anywhere you could do:
python3 venv_activate_this.py --virtualenv-dir /wherever/that/is
Now you can use vim with python and make it understand how to activate the correct virtual environment for things like ALE and YCM.
Also stored as a gist here: https://gist.github.com/nackjicholson/db83869b7931b0bc95fa9e0960921f1c
I used a different approach used in virtualenv itself:
# the current Python interpreter is not from the virtual environment
file = __file__
if file.endswith('.pyc'):
file = file[:-1]
venv_executable = PROJECT_DIR / 'venv' / 'bin' / 'python'
popen = subprocess.Popen([venv_executable, file] + sys.argv[1:])
raise SystemExit(popen.wait())