Как я могу активировать pyvenv vitrualenv из питона? (activ_this.py был удален?)

Я использую Python 3.4, и, создав pyvenv, я ищу, чтобы активировать его из процесса Python. С virtualenv я использовал activate_this.py, но это, кажется, ушел в pyvenv.

Есть ли сейчас простой способ эффективно изменить текущий переводчик на переводчик virtualenv? Я мог бы возиться с ПУТИ (что к чему activate_this.py сделал), но я бы хотел более простой и стабильный способ.

Это для использования в wsgi.py.

4 ответа

pyvenv и venv модуль не поддерживает это из коробки. Третья сторона virtualenv пакет поддерживает это с помощью activate_this.py, но эта функция не была включена во встроенный venv модуль.

Вы можете попробовать одолжить копию activate_this.py из virtualenv основанная среда; это похоже на работу, хотя я не могу поклясться, что это будет идеально (venv / pyvenv использует немного магии во время запуска; неясно, если все это реплицируется через activate_this.py).

virtualenv документы для него устарели для Python 3 (они утверждают, что вы используете execfile, которого не существует). Python 3 совместимая альтернатива будет:

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})

Ничего такого activate_this.py делает это волшебно, так что вы можете вручную выполнить те же изменения без мародерства из virtualenv (регулировка PATH, sys.path, sys.prefix и т. д.), но в этом случае заимствование значительно упрощает задачу.

Я использовал другой подход, используемый в virtualenv сам:

# 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())

сохраните следующее как файл активировать_это.py

      # -*- coding: utf-8 -*-
"""Activate virtualenv for current interpreter:

Use exec(open(this_file).read(), {'__file__': this_file}).

This can be used when you must use an existing Python interpreter, not the virtualenv bin/python.
"""
import os
import site
import sys

try:
    abs_file = os.path.abspath(__file__)
except NameError:
    raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))")

bin_dir = os.path.dirname(abs_file)
base = bin_dir[: -len("__BIN_NAME__") - 1]  # strip away the bin part from the __file__, plus the path separator

# prepend bin to PATH (this file is inside the bin directory)
os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep))
os.environ["VIRTUAL_ENV"] = base  # virtual env is right above bin directory

# add the virtual environments libraries to the host python import mechanism
prev_length = len(sys.path)
for lib in "__LIB_FOLDERS__".split(os.pathsep):
    path = os.path.realpath(os.path.join(bin_dir, lib))
    site.addsitedir(path.decode("utf-8") if "__DECODE_PATH__" else path)
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]

sys.real_prefix = sys.prefix
sys.prefix = base
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)

Я украл это сумасшедшее дерьмо из virtualenv сам проект. Вот

Сценарий запишет activ_this.py в вашу корзину виртуальной среды.

С поэзией можно делать:

poetry run python venv_activate_this.py

Для python venv сделайте:

source venv/bin/activate
python venv_activate_this.py

И из любого места вы можете сделать:

python3 venv_activate_this.py --virtualenv-dir /wherever/that/is

Теперь вы можете использовать vim с python и понять, как активировать правильную виртуальную среду для таких вещей, как ALE и YCM.

Также хранится здесь: https://gist.github.com/nackjicholson/db83869b7931b0bc95fa9e0960921f1c

Другие вопросы по тегам