venv — Создание виртуальных сред
Новое в версии 3.3.
Исходный код: Lib/venv/
Модуль venv предоставляет поддержку создания лёгких «виртуальных сред» со своими собственными каталогами сайта, необязательно изолированными от системных каталогов сайта. Каждая виртуальная среда имеет свой собственный бинарный файл Python (позволяющий создание сред с различными версиями Python) и может иметь свой собственный независимый набор установленных пакетов Python в своих каталогах сайта.
См. PEP 405 для получения дополнительной информации о виртуальных средах Python.
Примечание
Скрипт pyvenv устарел начиная с Python 3.6 в пользу использования python3 -m venv, чтобы предотвратить возможные путаницы относительно того, на каком интерпретаторе Python будет основана виртуальная среда.
1. Создание виртуальных сред
Создание виртуальных сред выполняется путём выполнения скрипта pyvenv.
pyvenv /path/to/new/virtual/environment
Выполнение этой команды создаёт целевой каталог (создавая любые родительские каталоги, которых ещё нет) и размещает в нём файл pyvenv.cfg с ключом home, указывающим на установку Python, с которой была запущена команда. Она также создаёт подкаталог bin (или Scripts в Windows), содержащий копию бинарного файла python (или бинарных файлов в случае Windows). Также создаётся подкаталог (изначально пустой) lib/pythonX.Y/site-packages (в Windows это Lib\site-packages).
В Windows, вам, возможно, придётся вызвать скрипт pyvenv следующим образом, если у вас отсутствуют необходимые настройки PATH и PATHEXT:
c:\Temp>c:\Python35\python c:\Python35\Tools\Scripts\pyvenv.py myenv
или эквивалентно:
c:\Temp>c:\Python35\python -m venv myenv
Команда, если выполняется с -h, покажет доступные опции:
usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
[--upgrade] [--without-pip]
ENV_DIR [ENV_DIR ...]
Creates virtual Python environments in one or more target directories.
positional arguments:
ENV_DIR A directory to create the environment in.
optional arguments:
-h, --help show this help message and exit
--system-site-packages Give the virtual environment access to the system
site-packages dir.
--symlinks Try to use symlinks rather than copies, when symlinks
are not the default for the platform.
--copies Try to use copies rather than symlinks, even when
symlinks are the default for the platform.
--clear Delete the contents of the environment directory if it
already exists, before environment creation.
--upgrade Upgrade the environment directory to use this version
of Python, assuming Python has been upgraded in-place.
--without-pip Skips installing or upgrading pip in the virtual
environment (pip is bootstrapped by default)
В зависимости от того, как вызвана функция venv, сообщение об использовании может незначительно отличаться, например, ссылаясь на pyvenv вместо venv.
Изменено в версии 3.4: Устанавливает pip по умолчанию, добавлена опции --without-pip и --copies
Изменено в версии 3.4: В предыдущих версиях, если целевой каталог уже существовал, возникала ошибка, если не была указана опция --clear или --upgrade. Теперь, если указан существующий каталог, его содержимое удаляется, и каталог обрабатывается так, как будто он был создан заново.
Созданный файл pyvenv.cfg также включает ключ include-system-site-packages, установленный в true если venv выполняется с опцией --system-site-packages, и false в противном случае.
Если опция --without-pip не указана, ensurepip будет вызвана для инициализации pip в виртуальной среде.
Можно указать несколько путей для pyvenv, в этом случае идентичная виртуальная среда будет создана по заданным параметрам в каждом указанном пути.
После создания venv её можно «активировать», используя скрипт в каталоге бинарных файлов venv. Вызов скрипта зависит от платформы:
| Платформа | Оболочка | Команда для активации виртуальной среды |
|---|---|---|
| Posix | bash/zsh | $ source <venv>/bin/activate |
| fish | $ . <venv>/bin/activate.fish | |
| csh/tcsh | $ source <venv>/bin/activate.csh | |
| Windows | cmd.exe | C:\> <venv>\Scripts\activate.bat |
| PowerShell | PS C:\> <venv>\Scripts\Activate.ps1 |
Вам не обязательно активировать среду; активация просто добавляет каталог бинарных файлов venv в ваш путь, так что «python» вызывает интерпретатор Python venv, и вы можете запускать установленные скрипты, не указывая их полный путь. Однако все скрипты, установленные в venv, должны запускаться без активации и автоматически запускаться с Python venv.
Вы можете деактивировать venv, набрав «deactivate» в своей оболочке. Точный механизм зависит от платформы: например, скрипт активации Bash определяет функцию «deactivate», а в Windows есть отдельные скрипты, называемые deactivate.bat и Deactivate.ps1, которые устанавливаются при создании venv.
Новое в версии 3.4: fish и csh скрипты активации.
Примечание
Виртуальная среда (также называемая venv) — это среда Python, в которой интерпретатор Python, библиотеки и скрипты, установленные в ней, изолированы от тех, что установлены в других виртуальных средах и (по умолчанию) от библиотек, установленных в «системном» Python, т. е. том, который установлен как часть вашей операционной системы.
venv — это древовидная структура каталогов, которая содержит файлы исполняемых программ Python и другие файлы, указывающие на то, что это venv.
Общие инструменты установки, такие как Setuptools и pip, работают ожидаемо с venv — то есть, когда venv активен, они устанавливают пакеты Python в venv, без необходимости явного указания.
Когда venv активен (т. е. работает интерпретатор Python venv), атрибуты sys.prefix и sys.exec_prefix указывают на базовый каталог venv, а sys.base_prefix и sys.base_exec_prefix — на установку Python вне venv, которая использовалась для создания venv. Если venv не активен, то sys.prefix такое же, как sys.base_prefix, а sys.exec_prefix такое же, как sys.base_exec_prefix (все они указывают на установку Python вне venv).
Когда venv активен, любые параметры, изменяющие путь установки, будут проигнорированы из всех файлов конфигурации distutils, чтобы предотвратить непреднамеренную установку проектов вне виртуальной среды.
При работе в командной оболочке пользователи могут активировать venv, выполнив скрипт activate в каталоге исполняемых файлов venv (точное имя файла зависит от оболочки), который добавляет каталог исполняемых файлов venv в переменную окружения PATH для текущей оболочки. В других ситуациях нет необходимости активировать venv — скрипты, установленные в venv, имеют строку shebang, которая указывает на интерпретатор Python venv. Это означает, что скрипт будет запущен с этим интерпретатором независимо от значения PATH. В Windows обработка строки shebang поддерживается, если установлен загрузчик Python для Windows (это было добавлено в Python 3.3 — см. PEP 397 для получения более подробной информации). Таким образом, двойной щелчок по установленному скрипту в окне проводника Windows должен запустить скрипт с правильным интерпретатором без необходимости ссылаться на его venv в PATH.
2. API
Описание вышеупомянутого высокоуровневого метода использует простой API, который предоставляет механизмы для сторонних создателей виртуальных сред для настройки создания среды в соответствии с их потребностями, класс EnvBuilder.
-
class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False) -
Класс
EnvBuilderпринимает следующие ключевые аргументы при создании:-
system_site_packages– логическое значение, указывающее, что системные модули Python site-packages должны быть доступны в среде (по умолчаниюFalse). -
clear– логическое значение, которое, если истинно, удалит содержимое любой существующей целевой директории перед созданием среды. -
symlinks– логическое значение, указывающее, следует ли пытаться создать символическую ссылку на двоичный файл Python (и любые необходимые DLL или другие двоичные файлы, например,pythonw.exe), а не копировать. По умолчаниюTrueв системах Linux и Unix, ноFalseв Windows. -
upgrade– логическое значение, которое, если истинно, обновит существующую среду с помощью работающего Python — для использования в случаях, когда этот Python был обновлен на месте (по умолчаниюFalse). -
with_pip– логическое значение, которое, если истинно, гарантирует установку pip в виртуальной среде. Это используется сensurepipс параметром--default-pip.
Изменено в версии 3.4: Добавлен параметр
with_pipСоздатели сторонних инструментов виртуальной среды могут свободно использовать предоставленный класс
EnvBuilderв качестве базового класса.Возвращаемый объект env-builder имеет метод
create:-
create(env_dir) -
Этот метод принимает в качестве обязательного аргумента путь (абсолютный или относительный к текущей директории) к целевой директории, которая должна содержать виртуальную среду. Метод
createсоздаст среду в указанной директории или вызовет соответствующее исключение.Метод
createклассаEnvBuilderдемонстрирует доступные хуки для настройки подклассов:def create(self, env_dir): """ Create a virtualized Python environment in a directory. env_dir is the target directory to create an environment in. """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) self.create_configuration(context) self.setup_python(context) self.setup_scripts(context) self.post_setup(context)Каждый из методов
ensure_directories(),create_configuration(),setup_python(),setup_scripts()иpost_setup()может быть переопределен.
-
ensure_directories(env_dir) -
Создаёт директорию среды и все необходимые поддиректории и возвращает контекстный объект. Это просто контейнер для атрибутов (таких как пути), используемый другими методами. Директории могут уже существовать, если были заданы
clearилиupgrade, чтобы разрешить работу с существующей директорией среды.
-
create_configuration(context) -
Создаёт файл конфигурации
pyvenv.cfgв среде.
-
setup_python(context) -
Создаёт копию исполняемого файла Python (и, в Windows, DLL) в среде. В POSIX-системах, если использовался определённый исполняемый файл
python3.x, будут созданы символические ссылки наpythonиpython3, указывающие на этот исполняемый файл, если файлы с этими именами ещё не существуют.
-
setup_scripts(context) -
Устанавливает скрипты активации, соответствующие платформе, в виртуальную среду.
-
post_setup(context) -
Заглушка-метод, который может быть переопределен в сторонних реализациях для предварительной установки пакетов в виртуальной среде или выполнения других шагов после создания.
Кроме того,
EnvBuilderпредоставляет этот служебный метод, который можно вызывать изsetup_scripts()илиpost_setup()в подклассах, чтобы помочь в установке пользовательских скриптов в виртуальную среду.-
install_scripts(context, path) -
path – путь к директории, которая должна содержать поддиректории «common», «posix», «nt», каждая содержащая скрипты, предназначенные для директории bin в среде. Содержимое «common» и директории, соответствующей
os.name, копируются после некоторой замены текста в плейсхолдерах:-
__VENV_DIR__заменяется абсолютным путём к директории среды. -
__VENV_NAME__заменяется именем среды (последний сегмент пути к директории среды). -
__VENV_PROMPT__заменяется приглашением (имя среды, окружённое скобками и последующим пробелом). -
__VENV_BIN_NAME__заменяется именем директории bin (либоbinлибоScripts). -
__VENV_PYTHON__заменяется абсолютным путём к исполняемому файлу среды.
Директории разрешается существовать (для случаев обновления существующей среды).
-
-
Также существует удобная функция на уровне модуля:
-
venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False) -
Создаёт экземпляр
EnvBuilderс заданными ключевыми аргументами и вызывает его методcreate()с аргументом env_dir.Изменено в версии 3.4: Добавлен параметр
with_pip
3. Пример расширения EnvBuilder
Следующий скрипт показывает, как расширить EnvBuilder, реализовав подкласс, который устанавливает setuptools и pip в созданную venv:
import os
import os.path
from subprocess import Popen, PIPE
import sys
from threading import Thread
from urllib.parse import urlparse
from urllib.request import urlretrieve
import venv
class ExtendedEnvBuilder(venv.EnvBuilder):
"""
This builder installs setuptools and pip so that you can pip or
easy_install other packages into the created environment.
:param nodist: If True, setuptools and pip are not installed into the
created environment.
:param nopip: If True, pip is not installed into the created
environment.
:param progress: If setuptools or pip are installed, the progress of the
installation can be monitored by passing a progress
callable. If specified, it is called with two
arguments: a string indicating some progress, and a
context indicating where the string is coming from.
The context argument can have one of three values:
'main', indicating that it is called from virtualize()
itself, and 'stdout' and 'stderr', which are obtained
by reading lines from the output streams of a subprocess
which is used to install the app.
If a callable is not specified, default progress
information is output to sys.stderr.
"""
def __init__(self, *args, **kwargs):
self.nodist = kwargs.pop('nodist', False)
self.nopip = kwargs.pop('nopip', False)
self.progress = kwargs.pop('progress', None)
self.verbose = kwargs.pop('verbose', False)
super().__init__(*args, **kwargs)
def post_setup(self, context):
"""
Set up any packages which need to be pre-installed into the
environment being created.
:param context: The information for the environment creation request
being processed.
"""
os.environ['VIRTUAL_ENV'] = context.env_dir
if not self.nodist:
self.install_setuptools(context)
# Can't install pip without setuptools
if not self.nopip and not self.nodist:
self.install_pip(context)
def reader(self, stream, context):
"""
Read lines from a subprocess' output stream and either pass to a progress
callable (if specified) or write progress information to sys.stderr.
"""
progress = self.progress
while True:
s = stream.readline()
if not s:
break
if progress is not None:
progress(s, context)
else:
if not self.verbose:
sys.stderr.write('.')
else:
sys.stderr.write(s.decode('utf-8'))
sys.stderr.flush()
stream.close()
def install_script(self, context, name, url):
_, _, path, _, _, _ = urlparse(url)
fn = os.path.split(path)[-1]
binpath = context.bin_path
distpath = os.path.join(binpath, fn)
# Download script into the env's binaries folder
urlretrieve(url, distpath)
progress = self.progress
if self.verbose:
term = '\n'
else:
term = ''
if progress is not None:
progress('Installing %s ...%s' % (name, term), 'main')
else:
sys.stderr.write('Installing %s ...%s' % (name, term))
sys.stderr.flush()
# Install in the env
args = [context.env_exe, fn]
p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
t1.start()
t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
t2.start()
p.wait()
t1.join()
t2.join()
if progress is not None:
progress('done.', 'main')
else:
sys.stderr.write('done.\n')
# Clean up - no longer needed
os.unlink(distpath)
def install_setuptools(self, context):
"""
Install setuptools in the environment.
:param context: The information for the environment creation request
being processed.
"""
url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
self.install_script(context, 'setuptools', url)
# clear up the setuptools archive which gets downloaded
pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
files = filter(pred, os.listdir(context.bin_path))
for f in files:
f = os.path.join(context.bin_path, f)
os.unlink(f)
def install_pip(self, context):
"""
Install pip in the environment.
:param context: The information for the environment creation request
being processed.
"""
url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
self.install_script(context, 'pip', url)
def main(args=None):
compatible = True
if sys.version_info < (3, 3):
compatible = False
elif not hasattr(sys, 'base_prefix'):
compatible = False
if not compatible:
raise ValueError('This script is only for use with '
'Python 3.3 or later')
else:
import argparse
parser = argparse.ArgumentParser(prog=__name__,
description='Creates virtual Python '
'environments in one or '
'more target '
'directories.')
parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
help='A directory to create the environment in.')
parser.add_argument('--no-setuptools', default=False,
action='store_true', dest='nodist',
help="Don't install setuptools or pip in the "
"virtual environment.")
parser.add_argument('--no-pip', default=False,
action='store_true', dest='nopip',
help="Don't install pip in the virtual "
"environment.")
parser.add_argument('--system-site-packages', default=False,
action='store_true', dest='system_site',
help='Give the virtual environment access to the '
'system site-packages dir.')
if os.name == 'nt':
use_symlinks = False
else:
use_symlinks = True
parser.add_argument('--symlinks', default=use_symlinks,
action='store_true', dest='symlinks',
help='Try to use symlinks rather than copies, '
'when symlinks are not the default for '
'the platform.')
parser.add_argument('--clear', default=False, action='store_true',
dest='clear', help='Delete the contents of the '
'environment directory if it '
'already exists, before '
'environment creation.')
parser.add_argument('--upgrade', default=False, action='store_true',
dest='upgrade', help='Upgrade the environment '
'directory to use this version '
'of Python, assuming Python '
'has been upgraded in-place.')
parser.add_argument('--verbose', default=False, action='store_true',
dest='verbose', help='Display the output '
'from the scripts which '
'install setuptools and pip.')
options = parser.parse_args(args)
if options.upgrade and options.clear:
raise ValueError('you cannot supply --upgrade and --clear together.')
builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
clear=options.clear,
symlinks=options.symlinks,
upgrade=options.upgrade,
nodist=options.nodist,
nopip=options.nopip,
verbose=options.verbose)
for d in options.dirs:
builder.create(d)
if __name__ == '__main__':
rc = 1
try:
main()
rc = 0
except Exception as e:
print('Error: %s' % e, file=sys.stderr)
sys.exit(rc)
Этот скрипт также доступен для скачивания онлайн.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/venv.html