Документация Python неофициальный перевод

venv.md

524 строк · 43.4 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.15/library/venv.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `venv` – Создание виртуальных окружений89Добавлено в версии 3.3.1011**Исходный код:** [Lib/venv/](https://python-all.ru/src/3.15/Lib/venv)1213---1415Модуль `venv` поддерживает создание легковесных «виртуальных окружений», каждое из которых имеет собственный независимый набор пакетов Python, установленных в каталог [`site`](https://python-all.ru/3.15/library/site.html#module-site). Виртуальное окружение создаётся на основе существующей установки Python, которая называется «базовым» Python этого окружения, и по умолчанию изолировано от пакетов базового окружения – доступны только те пакеты, которые явно установлены в виртуальное окружение. Для получения дополнительной информации см. [Виртуальные окружения](https://python-all.ru/3.15/library/sys_path_init.html#sys-path-init-virtual-environments) и `site` [документацию по виртуальным окружениям](https://python-all.ru/3.15/library/site.html#site-virtual-environments-configuration).1617При использовании внутри виртуального окружения стандартные инструменты установки, такие как [pip](https://python-all.ru/3.15/library/venv.html), устанавливают пакеты Python в это виртуальное окружение без необходимости явного указания.1819Виртуальное окружение (в числе прочего):2021- Содержит в себе конкретный интерпретатор Python, программные библиотеки и исполняемые файлы, необходимые для поддержки проекта (библиотеки или приложения). По умолчанию они изолированы от программ в других виртуальных окружениях и от интерпретаторов Python и библиотек, установленных в операционной системе.22- Находится в каталоге, который обычно называется `.venv` или `venv` внутри каталога проекта, либо в общем каталоге для множества виртуальных окружений, например `~/.virtualenvs`.23- Не помещается в системы управления версиями, такие как Git.24- Считается одноразовым – его должно быть легко удалить и воссоздать с нуля. Код проекта в окружение не помещается.25- Не считается переносимым или копируемым – достаточно воссоздать такое же окружение в нужном месте.2627Для получения дополнительной информации о виртуальных окружениях Python см. [**PEP 405**](https://python-all.ru/3.15/library/venv.html).2829> **См. также**30>31> [Руководство пользователя по упаковке Python: создание и использование виртуальных окружений](https://python-all.ru/3.15/library/venv.html)3233[Доступность](https://python-all.ru/3.15/library/intro.html#availability): не Android, не iOS, не WASI.3435Этот модуль не поддерживается на [мобильных платформах](https://python-all.ru/3.15/library/intro.html#mobile-availability) или [платформах WebAssembly](https://python-all.ru/3.15/library/intro.html#wasm-availability).3637## Создание виртуальных окружений3839[Виртуальные окружения](https://python-all.ru/3.15/library/venv.html#venv-def) создаются выполнением модуля `venv`:4041```shell42python -m venv /path/to/new/virtual/environment43```4445Это создаёт целевой каталог (включая родительские каталоги при необходимости) и помещает в него файл `pyvenv.cfg` с ключом `home`, указывающим на установку Python, из которой была запущена команда. Также создаётся подкаталог `bin` (или `Scripts` в Windows), содержащий копию или символическую ссылку на исполняемый файл Python (в зависимости от платформы или аргументов, указанных при создании окружения). Кроме того, создаётся подкаталог `lib/pythonX.Y/site-packages` (в Windows это `Lib\site-packages`). Если указан существующий каталог, он будет использован повторно.4647Изменено в версии 3.5: Теперь для создания виртуальных окружений рекомендуется использовать `venv`.4849Устарело с версии 3.6, удалено в версии 3.8: **pyvenv** был рекомендованным инструментом для создания виртуальных окружений для Python 3.3 и 3.4 и заменён в версии 3.5 на выполнение `venv` напрямую.5051В Windows команда `venv` выполняется следующим образом:5253```ps1con54PS> python -m venv C:\path\to\new\virtual\environment55```5657При запуске с флагом `-h` команда отображает доступные параметры:5859```text60usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]61            [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]62            [--without-scm-ignore-files]63            ENV_DIR [ENV_DIR ...]6465Creates virtual Python environments in one or more target directories.6667Once an environment has been created, you may wish to activate it, e.g. by68sourcing an activate script in its bin directory.69```7071#### `ENV_DIR`7273Обязательный аргумент, указывающий каталог, в котором будет создано окружение.7475#### `--system-site-packages`7677Предоставляет виртуальному окружению доступ к системному каталогу site-packages.7879#### `--symlinks`8081Пытаться использовать символические ссылки вместо копирования, если символические ссылки не являются настройкой по умолчанию для данной платформы.8283#### `--copies`8485Пытаться использовать копирование вместо символических ссылок, даже если символические ссылки установлены по умолчанию для данной платформы.8687#### `--clear`8889Удалить содержимое каталога окружения, если он уже существует, перед созданием окружения.9091#### `--upgrade`9293Обновить каталог окружения для использования этой версии Python в предположении, что Python был обновлён на месте.9495#### `--without-pip`9697Пропускает установку или обновление pip в виртуальном окружении (pip устанавливается по умолчанию).9899#### `--prompt <PROMPT>`100101Задаёт альтернативный префикс приглашения для этого окружения.102103#### `--upgrade-deps`104105Обновляет основные зависимости (pip) до последней версии в PyPI.106107#### `--without-scm-ignore-files`108109Пропускает добавление SCM-файлов игнорирования в каталог окружения (по умолчанию поддерживается Git).110111Изменено в версии 3.4: Устанавливает pip по умолчанию, добавлены опции `--without-pip` и `--copies` .112113Изменено в версии 3.4: В более ранних версиях, если целевой каталог уже существовал, возникала ошибка, если не была предоставлена опция `--clear` или `--upgrade`.114115Изменено в версии 3.9: Добавлена опция `--upgrade-deps` для обновления pip и setuptools до последних версий в PyPI.116117Изменено в версии 3.12: `setuptools` больше не является основной зависимостью venv.118119Изменено в версии 3.13: Добавлена опция `--without-scm-ignore-files`.120121Изменено в версии 3.13: `venv` теперь по умолчанию создаёт файл `.gitignore` для Git.122123> **Примечание**124>125> Хотя символические ссылки поддерживаются в Windows, они не рекомендуются. Особенно важно отметить, что двойной щелчок по `python.exe` в Проводнике разрешит символьную ссылку немедленно и проигнорирует виртуальное окружение.126127> **Примечание**128>129> В Microsoft Windows может потребоваться включить сценарий `Activate.ps1`, установив политику выполнения для пользователя. Это можно сделать, выполнив следующую команду PowerShell:130>131> ```powershell132> PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser133> ```134>135> См. [О политиках выполнения](https://python-all.ru/3.15/library/venv.html) для получения дополнительной информации.136137Созданный файл `pyvenv.cfg` также включает ключ `include-system-site-packages`, установленный в `true`, если `venv` запущен с опцией `--system-site-packages`, и в `false` в противном случае.138139Если не указана опция `--without-pip`, будет вызван [`ensurepip`](https://python-all.ru/3.15/library/ensurepip.html#module-ensurepip) для начальной установки `pip` в виртуальное окружение.140141Можно указать несколько путей для `venv`, в этом случае будет создано идентичное виртуальное окружение с заданными опциями для каждого указанного пути.142143## Как работают виртуальные окружения144145Когда интерпретатор Python выполняется из виртуального окружения, [`sys.prefix`](https://python-all.ru/3.15/library/sys.html#sys.prefix) и [`sys.exec_prefix`](https://python-all.ru/3.15/library/sys.html#sys.exec_prefix) указывают на каталоги виртуального окружения, тогда как [`sys.base_prefix`](https://python-all.ru/3.15/library/sys.html#sys.base_prefix) и [`sys.base_exec_prefix`](https://python-all.ru/3.15/library/sys.html#sys.base_exec_prefix) указывают на каталоги базового Python, использованного для создания окружения. Достаточно проверить `sys.prefix != sys.base_prefix`, чтобы определить, выполняется ли текущий интерпретатор из виртуального окружения.146147Виртуальное окружение может быть «активировано» с помощью сценария в его бинарном каталоге (`bin` в POSIX; `Scripts` в Windows). Это добавит этот каталог в начало вашей `PATH`, так что запуск **python** вызовет интерпретатор Python окружения, и вы сможете запускать установленные скрипты без указания полного пути. Вызов сценария активации зависит от платформы (`<venv>` должен быть заменён на путь к каталогу, содержащему виртуальное окружение):148149| Платформа | Оболочка | Команда активации виртуального окружения |150| --- | --- | --- |151| POSIX | bash/zsh | `$ source <venv>/bin/activate` |152| fish | `$ source <venv>/bin/activate.fish` |  |153| csh/tcsh | `$ source <venv>/bin/activate.csh` |  |154| pwsh | `$ <venv>/bin/Activate.ps1` |  |155| Windows | cmd.exe | `C:\> <venv>\Scripts\activate.bat` |156| PowerShell | `PS C:\> <venv>\Scripts\Activate.ps1` |  |157158Добавлено в версии 3.4: **fish** и **csh** скрипты активации.159160Добавлено в версии 3.8: скрипты активации PowerShell, установленные в POSIX для поддержки PowerShell Core.161162Нет особой *необходимости* активировать виртуальное окружение, так как можно просто указать полный путь к его интерпретатору Python при вызове Python. Кроме того, все скрипты, установленные в окружении, должны быть запускаемы без его активации.163164Для этого скрипты, установленные в виртуальные окружения, содержат строку shebang, указывающую на интерпретатор Python окружения, `#!/<path-to-venv>/bin/python`. Это означает, что скрипт будет запускаться с этим интерпретатором независимо от значения `PATH`. В Windows обработка строки shebang поддерживается, если установлен [Python install manager](https://python-all.ru/3.15/using/windows.html#launcher). Таким образом, двойной щелчок по установленному скрипту в окне Проводника Windows запустит его с правильным интерпретатором без необходимости активации окружения или нахождения его в `PATH`.165166Когда виртуальное окружение активировано, переменная окружения `VIRTUAL_ENV` устанавливается в путь к окружению. Поскольку явная активация виртуального окружения не требуется для его использования, `VIRTUAL_ENV` нельзя использовать для определения того, используется ли виртуальное окружение.167168> **Предупреждение**169>170> Поскольку скрипты, установленные в окружениях, не должны рассчитывать на активацию окружения, их shebang-строки содержат абсолютные пути к интерпретаторам своих окружений. Из-за этого окружения в общем случае непереносимы. Всегда должен быть простой способ воссоздать окружение (например, если есть файл требований `requirements.txt`, можно вызвать `pip install -r requirements.txt`, используя `pip` окружения, чтобы установить все необходимые пакеты). Если по какой-либо причине нужно переместить окружение в новое место, следует воссоздать его в нужном месте и удалить старое. Если окружение перемещается из-за перемещения родительского каталога, воссоздайте его в новом месте. В противном случае установленное в окружении ПО может работать некорректно.171172Деактивировать виртуальное окружение можно, введя в оболочке `deactivate`. Точный механизм зависит от платформы и является деталью внутренней реализации (обычно используется скрипт или функция оболочки).173174## API175176Описанный выше высокоуровневый метод использует простой API, предоставляющий механизмы для создателей сторонних виртуальных окружений, чтобы настраивать создание окружения по своему усмотрению – класс [`EnvBuilder`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder).177178#### `class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())`179180Класс `EnvBuilder` принимает следующие именованные аргументы при создании экземпляра:181182- *system\_site\_packages* – логическое значение, указывающее, что системные site-packages Python должны быть доступны окружению (по умолчанию `False`).183- *clear* – логическое значение: если истинно, удаляет содержимое существующего целевого каталога перед созданием окружения.184- *symlinks* – логическое значение, указывающее, следует ли пытаться создать символическую ссылку на двоичный файл Python вместо его копирования.185- *upgrade* – логическое значение: если истинно, обновит существующее окружение с помощью текущего Python – для случаев, когда Python был обновлён на месте (по умолчанию `False`).186- *with\_pip* – логическое значение: если истинно, гарантирует, что pip установлен в виртуальное окружение. Для этого используется [`ensurepip`](https://python-all.ru/3.15/library/ensurepip.html#module-ensurepip) с опцией `--default-pip`.187- *prompt* – строка, используемая после активации виртуального окружения (по умолчанию `None`, то есть будет использовано имя каталога окружения). Если указана специальная строка `"."`, в качестве приглашения используется базовое имя текущего каталога.188- *upgrade\_deps* – Обновляет базовые модули venv до последних версий на PyPI.189- *scm\_ignore\_files* – Создаёт файлы игнорирования для указанных систем управления версиями (SCM) из итерируемого объекта. Поддержка определяется наличием метода с именем `create_{scm}_ignore_file`. Единственное поддерживаемое по умолчанию значение – `"git"` через [`create_git_ignore_file()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.create_git_ignore_file).190191Изменено в версии 3.4: Добавлен параметр `with_pip`192193Изменено в версии 3.6: Добавлен параметр `prompt`194195Изменено в версии 3.9: Добавлен параметр `upgrade_deps`196197Изменено в версии 3.13: Добавлен параметр `scm_ignore_files`198199`EnvBuilder` может использоваться как базовый класс.200201#### `create(env_dir)`202203Создаёт виртуальное окружение путём указания целевого каталога (абсолютного или относительного по отношению к текущему каталогу), который будет содержать виртуальное окружение. Метод `create` либо создаст окружение в указанном каталоге, либо вызовет соответствующее исключение.204205Метод `create` класса `EnvBuilder` иллюстрирует точки расширения, доступные для настройки в подклассах:206207```python208def create(self, env_dir):209    """210    Создаёт виртуализированное окружение Python в указанном каталоге.211    Параметр env_dir – это целевой каталог, в котором создаётся окружение.212    """213    env_dir = os.path.abspath(env_dir)214    context = self.ensure_directories(env_dir)215    self.create_configuration(context)216    self.setup_python(context)217    self.setup_scripts(context)218    self.post_setup(context)219```220221Каждый из методов [`ensure_directories()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.ensure_directories), [`create_configuration()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.create_configuration), [`setup_python()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_python), [`setup_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_scripts) и [`post_setup()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.post_setup) может быть переопределён.222223#### `ensure_directories(env_dir)`224225Создаёт каталог окружения и все необходимые подкаталоги, которых ещё нет, и возвращает объект контекста. Этот объект контекста – просто контейнер для атрибутов (например, путей), используемых другими методами. Если `EnvBuilder` создаётся с аргументом `clear=True`, содержимое каталога окружения будет очищено, а затем все необходимые подкаталоги будут созданы заново.226227Возвращаемый объект контекста – это [`types.SimpleNamespace`](https://python-all.ru/3.15/library/types.html#types.SimpleNamespace) со следующими атрибутами:228229- `env_dir` – расположение виртуального окружения. Используется для `__VENV_DIR__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.install_scripts)).230- `env_name` – имя виртуального окружения. Используется для `__VENV_NAME__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.install_scripts)).231- `prompt` – приглашение, используемое скриптами активации. Используется для `__VENV_PROMPT__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.install_scripts)).232- `executable` – используемый исполняемый файл Python для виртуального окружения. Учитывает случай, когда виртуальное окружение создаётся из другого виртуального окружения.233- `inc_path` – путь include для виртуального окружения.234- `lib_path` – путь purelib для виртуального окружения.235- `platlib_path` – путь platlib для виртуального окружения.236- `bin_path` – путь скриптов для виртуального окружения.237- `bin_name` – имя пути скриптов относительно расположения виртуального окружения. Используется для `__VENV_BIN_NAME__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.install_scripts)).238- `env_exe` – имя интерпретатора Python в виртуальном окружении. Используется для `__VENV_PYTHON__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.install_scripts)).239- `env_exec_cmd` – имя интерпретатора Python с учётом перенаправлений файловой системы. Может использоваться для запуска Python в виртуальном окружении.240241Изменено в версии 3.11: *venv* [схема установки sysconfig](https://python-all.ru/3.15/library/sysconfig.html#installation-paths) используется для построения путей создаваемых каталогов.242243Изменено в версии 3.12: Атрибут `lib_path` был добавлен в контекст, и объект контекста был задокументирован.244245Изменено в версии 3.15: Атрибут `platlib_path` добавлен в контекст.246247#### `create_configuration(context)`248249Создаёт файл конфигурации `pyvenv.cfg` в окружении.250251#### `setup_python(context)`252253Создаёт копию или символическую ссылку на исполняемый файл Python в окружении. В системах POSIX, если был указан конкретный исполняемый файл `python3.x`, будут созданы символические ссылки на `python` и `python3`, указывающие на этот исполняемый файл, если файлы с такими именами уже не существуют.254255#### `setup_scripts(context)`256257Устанавливает скрипты активации, соответствующие платформе, в виртуальное окружение.258259#### `upgrade_dependencies(context)`260261Обновляет основные зависимые пакеты venv (в настоящее время [pip](https://python-all.ru/3.15/library/venv.html)) в окружении. Это делается путём вызова исполняемого файла `pip` в окружении.262263Добавлено в версии 3.9.264265Изменено в версии 3.12: [setuptools](https://python-all.ru/3.15/library/venv.html) больше не является основной зависимостью venv.266267#### `post_setup(context)`268269Метод-заглушка, который может быть переопределён в сторонних реализациях для предварительной установки пакетов в виртуальное окружение или выполнения других действий после создания.270271#### `install_scripts(context, path)`272273Этот метод можно вызывать из [`setup_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_scripts) или [`post_setup()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.post_setup) в подклассах для помощи в установке пользовательских скриптов в виртуальное окружение.274275*path* – путь к каталогу, который должен содержать подкаталоги `common`, `posix`, `nt`; каждый содержит скрипты, предназначенные для каталога `bin` в окружении. Содержимое каталогов `common` и соответствующего [`os.name`](https://python-all.ru/3.15/library/os.html#os.name) копируется после замены некоторых текстовых плейсхолдеров:276277- `__VENV_DIR__` заменяется на абсолютный путь к каталогу окружения.278- `__VENV_NAME__` заменяется на имя окружения (последний сегмент пути к каталогу окружения).279- `__VENV_PROMPT__` заменяется на приглашение (имя окружения в скобках и с последующим пробелом)280- `__VENV_BIN_NAME__` заменяется на имя каталога bin ( `bin` или `Scripts`).281- `__VENV_PYTHON__` заменяется на абсолютный путь к исполняемому файлу окружения.282283Каталоги могут существовать (на случай, когда обновляется существующее окружение).284285#### `create_git_ignore_file(context)`286287Создаёт файл `.gitignore` внутри виртуального окружения, что заставляет систему управления версиями Git игнорировать весь каталог.288289Добавлено в версии 3.13.290291Изменено в версии 3.7.2: В Windows теперь используются скрипты-перенаправители для `python[w].exe` вместо копирования самих исполняемых файлов. В версии 3.7.2 только [`setup_python()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_python) ничего не делает, если не запущен из сборки в исходном дереве.292293Изменено в версии 3.7.3: В Windows скрипты-перенаправители копируются как часть [`setup_python()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_python) вместо [`setup_scripts()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.setup_scripts). В версии 3.7.2 это было не так. При использовании символьных ссылок будут связаны исходные исполняемые файлы.294295Также существует удобная функция уровня модуля:296297#### `venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())`298299Создаёт экземпляр [`EnvBuilder`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder) с заданными именованными аргументами и вызывает его метод [`create()`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder.create) с аргументом *env\_dir*.300301Добавлено в версии 3.3.302303Изменено в версии 3.4: Добавлен параметр *with\_pip*304305Изменено в версии 3.6: Добавлен параметр *prompt*306307Изменено в версии 3.9: Добавлен параметр *upgrade\_deps*308309Изменено в версии 3.13: Добавлен параметр *scm\_ignore\_files*310311## Пример расширения `EnvBuilder`312313Следующий скрипт показывает, как расширить [`EnvBuilder`](https://python-all.ru/3.15/library/venv.html#venv.EnvBuilder), реализовав подкласс, который устанавливает setuptools и pip в созданное виртуальное окружение:314315```python316import os317import os.path318from subprocess import Popen, PIPE319import sys320from threading import Thread321from urllib.parse import urlsplit322from urllib.request import urlretrieve323import venv324325class ExtendedEnvBuilder(venv.EnvBuilder):326    """327    Данный построитель устанавливает setuptools и pip, чтобы с их помощью можно было328    устанавливать другие пакеты в созданное виртуальное окружение командой pip или easy_install.329330    :param nodist: Если истина, setuptools и pip не устанавливаются в331                   созданное виртуальное окружение.332    :param nopip: Если истина, pip не устанавливается в созданное333                  виртуальное окружение.334    :param progress: Если setuptools или pip устанавливаются, за ходом установки335                     можно следить, передав вызываемый объект для отслеживания прогресса.336                     Если он указан, то вызывается с двумя337                     аргументами: строкой, описывающей текущий этап, и338                     контекстом, указывающим, откуда пришла эта строка.339                     Аргумент context может принимать одно из трёх значений:340                     'main' – вызов происходит из самой virtualize(),341                     а также 'stdout' и 'stderr' – строки берутся342                     из потоков вывода подпроцесса, который343                     используется для установки приложения.344345                     Если вызываемый объект не указан, по умолчанию сведения о ходе выполнения346                     выводятся в sys.stderr.347    """348349    def __init__(self, *args, **kwargs):350        self.nodist = kwargs.pop('nodist', False)351        self.nopip = kwargs.pop('nopip', False)352        self.progress = kwargs.pop('progress', None)353        self.verbose = kwargs.pop('verbose', False)354        super().__init__(*args, **kwargs)355356    def post_setup(self, context):357        """358        Устанавливает пакеты, которые необходимо предварительно установить в создаваемое виртуальное окружение.359        создаваемое виртуальное окружение360361        обрабатываемого запроса на создание виртуального окружения362                        запрос на создание обрабатывается363        """364        os.environ['VIRTUAL_ENV'] = context.env_dir365        if not self.nodist:366            self.install_setuptools(context)367        # Читает строки из потока вывода подпроцесса и либо передаёт их вызываемому объекту для отслеживания хода выполнения368        if not self.nopip and not self.nodist:369            self.install_pip(context)370371    def reader(self, stream, context):372        """373        Читает строки из потока вывода подпроцесса и передаёт их в индикатор прогресса374        Загружает скрипт в папку с бинарными файлами виртуального окружения375        """376        progress = self.progress377        while True:378            s = stream.readline()379            if not s:380                break381            if progress is not None:382                progress(s, context)383            else:384                if not self.verbose:385                    sys.stderr.write('.')386                else:387                    sys.stderr.write(s.decode('utf-8'))388                sys.stderr.flush()389        stream.close()390391    def install_script(self, context, name, url):392        _, _, path, _, _ = urlsplit(url)393        fn = os.path.split(path)[-1]394        binpath = context.bin_path395        distpath = os.path.join(binpath, fn)396        # Устанавливает в виртуальное окружение397        urlretrieve(url, distpath)398        progress = self.progress399        if self.verbose:400            term = '\n'401        else:402            term = ''403        if progress is not None:404            progress('Installing %s ...%s' % (name, term), 'main')405        else:406            sys.stderr.write('Installing %s ...%s' % (name, term))407            sys.stderr.flush()408        # Очистка – больше не требуется409        args = [context.env_exe, fn]410        p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)411        t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))412        t1.start()413        t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))414        t2.start()415        p.wait()416        t1.join()417        t2.join()418        if progress is not None:419            progress('done.', 'main')420        else:421            sys.stderr.write('done.\n')422        # Очищает – больше не требуется423        os.unlink(distpath)424425    def install_setuptools(self, context):426        """427        Устанавливает setuptools в виртуальное окружение428429        обрабатываемого запроса на создание виртуального окружения430                        запрос на создание обрабатывается431        """432        url = "https://bootstrap.pypa.io/ez_setup.py"433        self.install_script(context, 'setuptools', url)434        # Устанавливает pip в виртуальное окружение.435        pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')436        files = filter(pred, os.listdir(context.bin_path))437        for f in files:438            f = os.path.join(context.bin_path, f)439            os.unlink(f)440441    def install_pip(self, context):442        """443        Устанавливает pip в виртуальное окружение444445        обрабатываемого запроса на создание виртуального окружения446                        запрос на создание обрабатывается447        """448        url = 'https://bootstrap.pypa.io/get-pip.py'449        self.install_script(context, 'pip', url)450451def main(args=None):452    import argparse453454    parser = argparse.ArgumentParser(prog=__name__,455                                     description='Creates virtual Python '456                                                 'environments in one or '457                                                 'more target '458                                                 'directories.')459    parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',460                        help='A directory in which to create the '461                             'virtual environment.')462    parser.add_argument('--no-setuptools', default=False,463                        action='store_true', dest='nodist',464                        help="Don't install setuptools or pip in the "465                             "virtual environment.")466    parser.add_argument('--no-pip', default=False,467                        action='store_true', dest='nopip',468                        help="Don't install pip in the virtual "469                             "environment.")470    parser.add_argument('--system-site-packages', default=False,471                        action='store_true', dest='system_site',472                        help='Give the virtual environment access to the '473                             'system site-packages dir.')474    if os.name == 'nt':475        use_symlinks = False476    else:477        use_symlinks = True478    parser.add_argument('--symlinks', default=use_symlinks,479                        action='store_true', dest='symlinks',480                        help='Try to use symlinks rather than copies, '481                             'when symlinks are not the default for '482                             'the platform.')483    parser.add_argument('--clear', default=False, action='store_true',484                        dest='clear', help='Delete the contents of the '485                                           'virtual environment '486                                           'directory if it already '487                                           'exists, before virtual '488                                           'environment creation.')489    parser.add_argument('--upgrade', default=False, action='store_true',490                        dest='upgrade', help='Upgrade the virtual '491                                             'environment directory to '492                                             'use this version of '493                                             'Python, assuming Python '494                                             'has been upgraded '495                                             'in-place.')496    parser.add_argument('--verbose', default=False, action='store_true',497                        dest='verbose', help='Display the output '498                                             'from the scripts which '499                                             'install setuptools and pip.')500    options = parser.parse_args(args)501    if options.upgrade and options.clear:502        raise ValueError('you cannot supply --upgrade and --clear together.')503    builder = ExtendedEnvBuilder(system_site_packages=options.system_site,504                                   clear=options.clear,505                                   symlinks=options.symlinks,506                                   upgrade=options.upgrade,507                                   nodist=options.nodist,508                                   nopip=options.nopip,509                                   verbose=options.verbose)510    for d in options.dirs:511        builder.create(d)512513if __name__ == '__main__':514    rc = 1515    try:516        main()517        rc = 0518    except Exception as e:519        print('Error: %s' % e, file=sys.stderr)520    sys.exit(rc)521```522523Этот скрипт также доступен для загрузки [онлайн](https://python-all.ru/3.15/library/venv.html).524