Spec-Zone.ru › Python 3.11

venv — Создание виртуальных окружений

Добавлено в версии 3.3.

Исходный код: Lib/venv/

Модуль venv поддерживает создание облегчённых «виртуальных окружений», каждое из которых имеет собственный независимый набор пакетов Python, установленных в каталогах site. Виртуальное окружение создаётся поверх существующей установки Python, называемой базовой версией Python виртуального окружения, и при необходимости может быть изолировано от пакетов базового окружения, так что будут доступны только пакеты, явно установленные в виртуальном окружении.

При использовании из виртуального окружения обычные инструменты установки, такие как pip, устанавливают пакеты Python в виртуальное окружение без необходимости явно указывать им это.

Виртуальное окружение (помимо прочего):

  • Используется для размещения определённого интерпретатора Python, а также программных библиотек и двоичных файлов, необходимых для поддержки проекта (библиотеки или приложения). По умолчанию они изолированы от программного обеспечения в других виртуальных окружениях и от интерпретаторов и библиотек Python, установленных в операционной системе.
  • Размещается в каталоге, который обычно называется venv или .venv в каталоге проекта, либо в каталоге-контейнере для множества виртуальных окружений, например ~/.virtualenvs.
  • Не включается в системы контроля версий, такие как Git.
  • Считается временным — его должно быть просто удалить и создать заново с нуля. Не помещайте код проекта в это окружение.
  • Не предназначено для перемещения или копирования — просто создайте такое же окружение в целевом расположении.

Дополнительные сведения о виртуальных окружениях Python см. в PEP 405.

См. также

Руководство пользователя по упаковке Python: создание и использование виртуальных окружений

Доступность: недоступен в Emscripten и WASI.

Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. Дополнительные сведения см. в разделе Платформы WebAssembly.

Создание виртуальных окружений

Виртуальные окружения создаются выполнением команды venv:

python -m venv /path/to/new/virtual/environment

Выполнение этой команды создаёт целевой каталог (вместе со всеми ещё не существующими родительскими каталогами) и помещает в него файл pyvenv.cfg с ключом home, указывающим на установку Python, из которой была запущена команда (обычное название целевого каталога — .venv). Также создаётся подкаталог bin (или Scripts в Windows), содержащий копию или символическую ссылку на двоичный файл (файлы) Python (в зависимости от платформы или аргументов, использованных при создании окружения). Кроме того, создаётся (изначально пустой) подкаталог lib/pythonX.Y/site-packages (в Windows это Lib\site-packages). Если указан существующий каталог, он будет использован повторно.

Изменено в версии 3.5: Теперь для создания виртуальных окружений рекомендуется использовать venv.

Устарело начиная с версии 3.6: pyvenv был рекомендуемым инструментом для создания виртуальных окружений в Python 3.3 и 3.4 и считается устаревшим в Python 3.6.

В Windows вызовите команду venv следующим образом:

c:\>c:\Python35\python -m venv c:\path\to\myenv

Или, если вы настроили переменные PATH и PATHEXT для своей установки Python:

c:\>python -m venv c:\path\to\myenv

Если запустить команду с параметром -h, будут показаны доступные параметры:

usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
            [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]
            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)
  --prompt PROMPT       Provides an alternative prompt prefix for this
                        environment.
  --upgrade-deps        Upgrade core dependencies: pip setuptools to the
                        latest version in PyPI

Once an environment has been created, you may wish to activate it, e.g. by
sourcing an activate script in its bin directory.

Изменено в версии 3.9: Добавлен параметр --upgrade-deps для обновления pip и setuptools до последних версий на PyPI

Изменено в версии 3.4: Установка pip теперь выполняется по умолчанию; добавлены параметры --without-pip и --copies

Изменено в версии 3.4: В более ранних версиях, если целевой каталог уже существовал, возникала ошибка, если не был указан параметр --clear или --upgrade.

Примечание

Хотя в Windows поддерживаются символические ссылки, их использование не рекомендуется. Обратите особое внимание: двойной щелчок по python.exe в Проводнике немедленно разрешит символическую ссылку и проигнорирует виртуальное окружение.

Примечание

В Microsoft Windows может потребоваться включить сценарий Activate.ps1, задав политику выполнения для пользователя. Для этого выполните следующую команду PowerShell:

PS C:> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Дополнительные сведения см. в разделе О политиках выполнения.

Созданный файл pyvenv.cfg также содержит ключ include-system-site-packages, значение которого равно true, если venv запущена с параметром --system-site-packages, и false в противном случае.

Если не указан параметр --without-pip, для установки pip в виртуальное окружение будет вызван ensurepip.

Команде venv можно передать несколько путей; в этом случае в каждом указанном пути будет создано одинаковое виртуальное окружение с учётом заданных параметров.

Как работают виртуальные окружения

Когда интерпретатор Python запущен из виртуального окружения, sys.prefix и sys.exec_prefix указывают на каталоги виртуального окружения, а sys.base_prefix и sys.base_exec_prefix — на каталоги базовой версии Python, использованной для создания окружения. Чтобы определить, запущен ли текущий интерпретатор из виртуального окружения, достаточно проверить sys.prefix != sys.base_prefix.

Виртуальное окружение можно «активировать» с помощью сценария в его каталоге двоичных файлов (bin в POSIX; Scripts в Windows). Это добавит данный каталог в начало вашего PATH, чтобы при запуске python вызывался интерпретатор Python из окружения и можно было запускать установленные сценарии без указания полного пути к ним. Запуск сценария активации зависит от платформы (<venv> следует заменить путём к каталогу, содержащему виртуальное окружение):

Платформа

Оболочка

Команда для активации виртуального окружения

POSIX

bash/zsh

$ source <venv>/bin/activate

fish

$ source <venv>/bin/activate.fish

csh/tcsh

$ source <venv>/bin/activate.csh

PowerShell

$ <venv>/bin/Activate.ps1

Windows

cmd.exe

C:\> <venv>\Scripts\activate.bat

PowerShell

PS C:\> <venv>\Scripts\Activate.ps1

Добавлено в версии 3.4: Сценарии активации для fish и csh.

Добавлено в версии 3.8: Сценарии активации PowerShell, устанавливаемые в POSIX для поддержки PowerShell Core.

Вам не обязательно нужно активировать виртуальное окружение: при запуске Python можно просто указать полный путь к интерпретатору Python из этого окружения. Кроме того, все сценарии, установленные в окружении, должны запускаться и без его активации.

Для этого у сценариев, установленных в виртуальных окружениях, есть строка «shebang», указывающая на интерпретатор Python из окружения, например #!/<path-to-venv>/bin/python. Это означает, что сценарий будет запускаться с этим интерпретатором независимо от значения PATH. В Windows обработка строки «shebang» поддерживается при установленном средстве запуска Python для Windows. Поэтому при двойном щелчке по установленному сценарию в окне Проводника Windows он должен запускаться с правильным интерпретатором без необходимости активировать окружение или добавлять его в PATH.

При активации виртуального окружения переменной среды VIRTUAL_ENV присваивается путь к окружению. Поскольку для использования виртуального окружения его не требуется явно активировать, нельзя полагаться на VIRTUAL_ENV при определении того, используется ли виртуальное окружение.

Предупреждение

Поскольку сценарии, установленные в окружениях, не должны рассчитывать на то, что окружение активировано, строки shebang содержат абсолютные пути к интерпретаторам окружения. Поэтому в общем случае окружения изначально непереносимы. У вас всегда должен быть простой способ воссоздать окружение (например, если у вас есть файл требований requirements.txt, можно вызвать pip install -r requirements.txt с помощью pip окружения, чтобы установить все необходимые пакеты). Если по какой-либо причине вам нужно переместить окружение в новое расположение, создайте его заново в нужном месте и удалите окружение в старом расположении. Если окружение перемещено из-за перемещения родительского каталога, создайте окружение заново в новом расположении. В противном случае установленное в окружении программное обеспечение может работать неправильно.

Деактивировать виртуальное окружение можно, введя в оболочке deactivate. Точный способ зависит от платформы и является деталью внутренней реализации (обычно используется сценарий или функция оболочки).

API

Описанный выше высокоуровневый метод использует простой API, предоставляющий сторонним разработчикам инструментов для создания виртуальных окружений механизмы настройки их создания в соответствии со своими потребностями — класс EnvBuilder.

class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False)

При создании экземпляра класса EnvBuilder принимает следующие именованные аргументы:

  • system_site_packages — логическое значение, указывающее, должны ли системные пакеты site-packages Python быть доступны окружению (по умолчанию False).
  • clear — логическое значение, которое при значении true приводит к удалению содержимого любого существующего целевого каталога перед созданием окружения.
  • symlinks — логическое значение, указывающее, следует ли попытаться создать символическую ссылку на двоичный файл Python вместо его копирования.
  • upgrade — логическое значение, которое при значении true обновляет существующее окружение с помощью запущенной версии Python; используется, если эта версия Python была обновлена на месте (по умолчанию False).
  • with_pip — логическое значение, которое при значении true гарантирует установку pip в виртуальное окружение. Для этого используется ensurepip с параметром --default-pip.
  • prompt — строка, используемая после активации виртуального окружения (по умолчанию None, что означает использование имени каталога окружения). Если указана специальная строка ".", в качестве приглашения используется базовое имя текущего каталога.
  • upgrade_deps — обновление базовых модулей venv до последних версий на PyPI

Изменено в версии 3.4: Добавлен параметр with_pip

Изменено в версии 3.6: Добавлен параметр prompt

Изменено в версии 3.9: Добавлен параметр upgrade_deps

Разработчики сторонних инструментов для создания виртуальных окружений могут использовать предоставленный класс EnvBuilder в качестве базового класса.

Возвращаемый объект для создания окружения имеет метод 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)

Создаёт каталог окружения и все необходимые подкаталоги, которые ещё не существуют, и возвращает объект контекста. Этот объект контекста служит контейнером атрибутов (например, путей), используемых другими методами. Если класс EnvBuilder создан с аргументом clear=True, содержимое каталога окружения будет удалено, а затем все необходимые подкаталоги будут созданы заново.

Возвращаемый объект контекста — это types.SimpleNamespace со следующими атрибутами:

  • env_dir — расположение виртуального окружения. Используется для __VENV_DIR__ в сценариях активации (см. install_scripts()).
  • env_name — имя виртуального окружения. Используется для __VENV_NAME__ в сценариях активации (см. install_scripts()).
  • prompt — приглашение, используемое сценариями активации. Используется для __VENV_PROMPT__ в сценариях активации (см. install_scripts()).
  • executable — исполняемый файл Python, используемый виртуальным окружением. Учитывается случай, когда виртуальное окружение создано из другого виртуального окружения.
  • inc_path — путь include виртуального окружения.
  • lib_path — путь purelib виртуального окружения.
  • bin_path — путь к сценариям виртуального окружения.
  • bin_name — имя каталога сценариев относительно расположения виртуального окружения. Используется для __VENV_BIN_NAME__ в сценариях активации (см. install_scripts()).
  • env_exe — имя интерпретатора Python в виртуальном окружении. Используется для __VENV_PYTHON__ в сценариях активации (см. install_scripts()).
  • env_exec_cmd — имя интерпретатора Python с учётом перенаправлений файловой системы. Его можно использовать для запуска Python в виртуальном окружении.

Изменено в версии 3.11: Для формирования путей созданных каталогов используется схема установки sysconfig venv.

create_configuration(context)

Создаёт в окружении файл конфигурации pyvenv.cfg.

setup_python(context)

Создаёт копию исполняемого файла Python в окружении или символическую ссылку на него. В системах POSIX, если использовался определённый исполняемый файл python3.x, будут созданы символические ссылки python и python3, указывающие на этот исполняемый файл, если файлы с такими именами ещё не существуют.

setup_scripts(context)

Устанавливает в виртуальное окружение сценарии активации, подходящие для данной платформы.

upgrade_dependencies(context)

Обновляет в окружении основные пакеты-зависимости venv (в настоящее время pip и setuptools). Для этого запускается исполняемый файл pip в окружении.

Добавлено в версии 3.9.

post_setup(context)

Метод-заглушка, который можно переопределить в сторонних реализациях для предварительной установки пакетов в виртуальное окружение или выполнения других действий после его создания.

Изменено в версии 3.7.2: В Windows для python[w].exe теперь используются сценарии перенаправления вместо копирования настоящих двоичных файлов. В версии 3.7.2 метод setup_python() ничего не делает, если запуск не производится из сборки в дереве исходного кода.

Изменено в версии 3.7.3: В Windows сценарии перенаправления копируются методом setup_python(), а не методом setup_scripts(). В версии 3.7.2 это работало иначе. При использовании символических ссылок связываются исходные исполняемые файлы.

Кроме того, 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, prompt=None, upgrade_deps=False)

Создаёт EnvBuilder с заданными именованными аргументами и вызывает его метод create(), передавая аргумент env_dir.

Добавлено в версии 3.3.

Изменено в версии 3.4: Добавлен параметр with_pip

Изменено в версии 3.6: Добавлен параметр prompt

Изменено в версии 3.9: Добавлен параметр upgrade_deps

Пример расширения EnvBuilder

Следующий сценарий показывает, как расширить EnvBuilder, реализовав подкласс, который устанавливает setuptools и pip в созданное виртуальное окружение:

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 virtual environment.

    :param nodist: If true, setuptools and pip are not installed into the
                   created virtual environment.
    :param nopip: If true, pip is not installed into the created
                  virtual 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
        virtual environment being created.

        :param context: The information for the virtual 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 virtual environment'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 virtual environment
        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 virtual environment.

        :param context: The information for the virtual 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 virtual environment.

        :param context: The information for the virtual environment
                        creation request being processed.
        """
        url = 'https://bootstrap.pypa.io/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 in which to create the '
                                 'virtual environment.')
        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 '
                                               'virtual environment '
                                               'directory if it already '
                                               'exists, before virtual '
                                               'environment creation.')
        parser.add_argument('--upgrade', default=False, action='store_true',
                            dest='upgrade', help='Upgrade the virtual '
                                                 '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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/venv.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API