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

venv.md

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

1> **Источник:** https://python-all.ru/3.12/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.12/Lib/venv)1213---1415Модуль `venv` поддерживает создание легковесных «виртуальных окружений», каждое со своим независимым набором пакетов Python, установленных в собственные каталоги [`site`](https://python-all.ru/3.12/library/site.html#module-site). Виртуальное окружение создаётся поверх существующей установки Python (она называется «базовым» Python виртуального окружения) и может быть изолировано от пакетов базового окружения – тогда будут доступны только те пакеты, которые явно установлены в виртуальное окружение.1617При использовании внутри виртуального окружения стандартные инструменты установки, такие как [pip](https://python-all.ru/3.12/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.12/library/venv.html).2829> **См. также**30>31> [Руководство пользователя по упаковке Python: создание и использование виртуальных окружений](https://python-all.ru/3.12/library/venv.html)3233[Доступность](https://python-all.ru/3.12/library/intro.html#availability): not Emscripten, not WASI.3435Этот модуль не работает или недоступен на платформах WebAssembly `wasm32-emscripten` и `wasm32-wasi`. См. [платформы WebAssembly](https://python-all.ru/3.12/library/intro.html#wasm-availability) для получения дополнительной информации.3637## Создание виртуальных окружений3839[Виртуальные окружения](https://python-all.ru/3.12/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 это `Libsite-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            ENV_DIR [ENV_DIR ...]6364Creates virtual Python environments in one or more target directories.6566positional arguments:67  ENV_DIR               A directory to create the environment in.6869options:70  -h, --help            show this help message and exit71  --system-site-packages72                        Give the virtual environment access to the system73                        site-packages dir.74  --symlinks            Try to use symlinks rather than copies, when75                        symlinks are not the default for the platform.76  --copies              Try to use copies rather than symlinks, even when77                        symlinks are the default for the platform.78  --clear               Delete the contents of the environment directory79                        if it already exists, before environment creation.80  --upgrade             Upgrade the environment directory to use this81                        version of Python, assuming Python has been82                        upgraded in-place.83  --without-pip         Skips installing or upgrading pip in the virtual84                        environment (pip is bootstrapped by default)85  --prompt PROMPT       Provides an alternative prompt prefix for this86                        environment.87  --upgrade-deps        Upgrade core dependencies (pip) to the latest88                        version in PyPI8990Once an environment has been created, you may wish to activate it, e.g. by91sourcing an activate script in its bin directory.92```9394Изменено в версии 3.4: Устанавливает pip по умолчанию, добавлены опции `--without-pip` и `--copies` .9596Изменено в версии 3.4: В более ранних версиях, если целевой каталог уже существовал, возникала ошибка, если не была предоставлена опция `--clear` или `--upgrade`.9798Изменено в версии 3.9: Добавлена опция `--upgrade-deps` для обновления pip и setuptools до последних версий в PyPI.99100Изменено в версии 3.12: `setuptools` больше не является основной зависимостью venv.101102> **Примечание**103>104> Хотя символические ссылки поддерживаются в Windows, они не рекомендуются. Особенно важно отметить, что двойной щелчок по `python.exe` в Проводнике разрешит символьную ссылку немедленно и проигнорирует виртуальное окружение.105106> **Примечание**107>108> В Microsoft Windows может потребоваться включить сценарий `Activate.ps1`, установив политику выполнения для пользователя. Это можно сделать, выполнив следующую команду PowerShell:109>110> ```powershell111> PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser112> ```113>114> См. [О политиках выполнения](https://python-all.ru/3.12/library/venv.html) для получения дополнительной информации.115116Созданный файл `pyvenv.cfg` также включает ключ `include-system-site-packages`, установленный в `true`, если `venv` запущен с опцией `--system-site-packages`, и в `false` в противном случае.117118Если не указана опция `--without-pip`, будет вызван [`ensurepip`](https://python-all.ru/3.12/library/ensurepip.html#module-ensurepip) для начальной установки `pip` в виртуальное окружение.119120Можно указать несколько путей для `venv`, в этом случае будет создано идентичное виртуальное окружение с заданными опциями для каждого указанного пути.121122## Как работают виртуальные окружения123124Когда интерпретатор Python выполняется из виртуального окружения, [`sys.prefix`](https://python-all.ru/3.12/library/sys.html#sys.prefix) и [`sys.exec_prefix`](https://python-all.ru/3.12/library/sys.html#sys.exec_prefix) указывают на каталоги виртуального окружения, тогда как [`sys.base_prefix`](https://python-all.ru/3.12/library/sys.html#sys.base_prefix) и [`sys.base_exec_prefix`](https://python-all.ru/3.12/library/sys.html#sys.base_exec_prefix) указывают на каталоги базового Python, использованного для создания окружения. Достаточно проверить `sys.prefix != sys.base_prefix`, чтобы определить, выполняется ли текущий интерпретатор из виртуального окружения.125126Виртуальное окружение может быть «активировано» с помощью сценария в его бинарном каталоге (`bin` в POSIX; `Scripts` в Windows). Это добавит этот каталог в начало вашей `PATH`, так что запуск **python** вызовет интерпретатор Python окружения, и вы сможете запускать установленные скрипты без указания полного пути. Вызов сценария активации зависит от платформы (`<venv>` должен быть заменён на путь к каталогу, содержащему виртуальное окружение):127128| Платформа | Оболочка | Команда активации виртуального окружения |129| --- | --- | --- |130| POSIX | bash/zsh | `$ source <venv>/bin/activate` |131| fish | `$ source <venv>/bin/activate.fish` |  |132| csh/tcsh | `$ source <venv>/bin/activate.csh` |  |133| pwsh | `$ <venv>/bin/Activate.ps1` |  |134| Windows | cmd.exe | `C:\> <venv>\Scripts\activate.bat` |135| PowerShell | `PS C:\> <venv>\Scripts\Activate.ps1` |  |136137Добавлено в версии 3.4: **fish** и **csh** скрипты активации.138139Добавлено в версии 3.8: скрипты активации PowerShell, установленные в POSIX для поддержки PowerShell Core.140141Нет особой *необходимости* активировать виртуальное окружение, так как можно просто указать полный путь к его интерпретатору Python при вызове Python. Кроме того, все скрипты, установленные в окружении, должны быть запускаемы без его активации.142143Чтобы добиться этого, скрипты, установленные в виртуальные окружения, имеют shebang-строку, указывающую на интерпретатор Python окружения, `#!/<path-to-venv>/bin/python`. Это означает, что скрипт будет запускаться этим интерпретатором независимо от значения `PATH`. На Windows обработка shebang-строки поддерживается, если установлен [Python Launcher for Windows](https://python-all.ru/3.12/using/windows.html#launcher). Таким образом, двойной щелчок по установленному скрипту в окне Проводника Windows запустит его с правильным интерпретатором без необходимости активации окружения или нахождения в `PATH`.144145Когда виртуальное окружение активировано, переменная окружения `VIRTUAL_ENV` устанавливается в путь к окружению. Поскольку явная активация виртуального окружения не требуется для его использования, `VIRTUAL_ENV` нельзя использовать для определения того, используется ли виртуальное окружение.146147> **Предупреждение**148>149> Поскольку скрипты, установленные в окружениях, не должны рассчитывать на активацию окружения, их shebang-строки содержат абсолютные пути к интерпретаторам своих окружений. Из-за этого окружения в общем случае непереносимы. Всегда должен быть простой способ воссоздать окружение (например, если есть файл требований `requirements.txt`, можно вызвать `pip install -r requirements.txt`, используя `pip` окружения, чтобы установить все необходимые пакеты). Если по какой-либо причине нужно переместить окружение в новое место, следует воссоздать его в нужном месте и удалить старое. Если окружение перемещается из-за перемещения родительского каталога, воссоздайте его в новом месте. В противном случае установленное в окружении ПО может работать некорректно.150151Деактивировать виртуальное окружение можно, введя в оболочке `deactivate`. Точный механизм зависит от платформы и является деталью внутренней реализации (обычно используется скрипт или функция оболочки).152153## API154155Описанный выше высокоуровневый метод использует простой API, предоставляющий механизмы для создателей сторонних виртуальных окружений, чтобы настраивать создание окружения по своему усмотрению – класс [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder).156157#### `class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False)`158159Класс [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder) принимает следующие именованные аргументы при создании экземпляра:160161- *system\_site\_packages* – логическое значение, указывающее, что системные site-packages Python должны быть доступны окружению (по умолчанию `False`).162- *clear* – логическое значение: если истинно, удаляет содержимое существующего целевого каталога перед созданием окружения.163- *symlinks* – логическое значение, указывающее, следует ли пытаться создать символическую ссылку на двоичный файл Python вместо его копирования.164- *upgrade* – логическое значение: если истинно, обновит существующее окружение с помощью текущего Python – для случаев, когда Python был обновлён на месте (по умолчанию `False`).165- *with\_pip* – логическое значение: если истинно, гарантирует, что pip установлен в виртуальное окружение. Для этого используется [`ensurepip`](https://python-all.ru/3.12/library/ensurepip.html#module-ensurepip) с опцией `--default-pip`.166- *prompt* – строка, используемая после активации виртуального окружения (по умолчанию `None`, то есть будет использовано имя каталога окружения). Если указана специальная строка `"."`, в качестве приглашения используется базовое имя текущего каталога.167- *upgrade\_deps* – Обновляет базовые модули venv до последних версий на PyPI.168169Изменено в версии 3.4: Добавлен параметр `with_pip`170171Изменено в версии 3.6: Добавлен параметр `prompt`172173Изменено в версии 3.9: Добавлен параметр `upgrade_deps`174175[`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder) может использоваться как базовый класс.176177#### `create(env_dir)`178179Создаёт виртуальное окружение путём указания целевого каталога (абсолютного или относительного по отношению к текущему каталогу), который будет содержать виртуальное окружение. Метод `create` либо создаст окружение в указанном каталоге, либо вызовет соответствующее исключение.180181Метод `create` класса [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder) иллюстрирует точки расширения, доступные для настройки в подклассах:182183```python184def create(self, env_dir):185    """186    Создаёт виртуализированное окружение Python в указанном каталоге.187    Параметр env_dir – это целевой каталог, в котором создаётся окружение.188    """189    env_dir = os.path.abspath(env_dir)190    context = self.ensure_directories(env_dir)191    self.create_configuration(context)192    self.setup_python(context)193    self.setup_scripts(context)194    self.post_setup(context)195```196197Каждый из методов [`ensure_directories()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.ensure_directories), [`create_configuration()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.create_configuration), [`setup_python()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_python), [`setup_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_scripts) и [`post_setup()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.post_setup) может быть переопределён.198199#### `ensure_directories(env_dir)`200201Создаёт каталог окружения и все необходимые подкаталоги, которых ещё нет, и возвращает объект контекста. Этот объект контекста – просто контейнер для атрибутов (например, путей), используемых другими методами. Если [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder) создаётся с аргументом `clear=True`, содержимое каталога окружения будет очищено, а затем все необходимые подкаталоги будут созданы заново.202203Возвращаемый объект контекста – это [`types.SimpleNamespace`](https://python-all.ru/3.12/library/types.html#types.SimpleNamespace) со следующими атрибутами:204205- `env_dir` – расположение виртуального окружения. Используется для `__VENV_DIR__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.install_scripts)).206- `env_name` – имя виртуального окружения. Используется для `__VENV_NAME__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.install_scripts)).207- `prompt` – приглашение, используемое скриптами активации. Используется для `__VENV_PROMPT__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.install_scripts)).208- `executable` – используемый исполняемый файл Python для виртуального окружения. Учитывает случай, когда виртуальное окружение создаётся из другого виртуального окружения.209- `inc_path` – путь include для виртуального окружения.210- `lib_path` – путь purelib для виртуального окружения.211- `bin_path` – путь скриптов для виртуального окружения.212- `bin_name` – имя пути скриптов относительно расположения виртуального окружения. Используется для `__VENV_BIN_NAME__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.install_scripts)).213- `env_exe` – имя интерпретатора Python в виртуальном окружении. Используется для `__VENV_PYTHON__` в скриптах активации (см. [`install_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.install_scripts)).214- `env_exec_cmd` – имя интерпретатора Python с учётом перенаправлений файловой системы. Может использоваться для запуска Python в виртуальном окружении.215216Изменено в версии 3.11: *venv* [схема установки sysconfig](https://python-all.ru/3.12/library/sysconfig.html#installation-paths) используется для построения путей создаваемых каталогов.217218Изменено в версии 3.12: Атрибут `lib_path` был добавлен в контекст, и объект контекста был задокументирован.219220#### `create_configuration(context)`221222Создаёт файл конфигурации `pyvenv.cfg` в окружении.223224#### `setup_python(context)`225226Создаёт копию или символическую ссылку на исполняемый файл Python в окружении. В системах POSIX, если был указан конкретный исполняемый файл `python3.x`, будут созданы символические ссылки на `python` и `python3`, указывающие на этот исполняемый файл, если файлы с такими именами уже не существуют.227228#### `setup_scripts(context)`229230Устанавливает скрипты активации, соответствующие платформе, в виртуальное окружение.231232#### `upgrade_dependencies(context)`233234Обновляет основные зависимые пакеты venv (в настоящее время [pip](https://python-all.ru/3.12/library/venv.html)) в окружении. Это делается путём вызова исполняемого файла `pip` в окружении.235236Добавлено в версии 3.9.237238Изменено в версии 3.12: [setuptools](https://python-all.ru/3.12/library/venv.html) больше не является основной зависимостью venv.239240#### `post_setup(context)`241242Метод-заглушка, который может быть переопределён в сторонних реализациях для предварительной установки пакетов в виртуальное окружение или выполнения других действий после создания.243244#### `install_scripts(context, path)`245246Этот метод можно вызывать из [`setup_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_scripts) или [`post_setup()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.post_setup) в подклассах для помощи в установке пользовательских скриптов в виртуальное окружение.247248*path* – путь к каталогу, который должен содержать подкаталоги `common`, `posix`, `nt`; каждый содержит скрипты, предназначенные для каталога `bin` в окружении. Содержимое каталогов `common` и соответствующего [`os.name`](https://python-all.ru/3.12/library/os.html#os.name) копируется после замены некоторых текстовых плейсхолдеров:249250- `__VENV_DIR__` заменяется на абсолютный путь к каталогу окружения.251- `__VENV_NAME__` заменяется на имя окружения (последний сегмент пути к каталогу окружения).252- `__VENV_PROMPT__` заменяется на приглашение (имя окружения в скобках и с последующим пробелом)253- `__VENV_BIN_NAME__` заменяется на имя каталога bin ( `bin` или `Scripts`).254- `__VENV_PYTHON__` заменяется на абсолютный путь к исполняемому файлу окружения.255256Каталоги могут существовать (на случай, когда обновляется существующее окружение).257258Изменено в версии 3.7.2: В Windows теперь используются скрипты-перенаправители для `python[w].exe` вместо копирования самих исполняемых файлов. В версии 3.7.2 только [`setup_python()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_python) ничего не делает, если не запущен из сборки в исходном дереве.259260Изменено в версии 3.7.3: В Windows скрипты-перенаправители копируются как часть [`setup_python()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_python) вместо [`setup_scripts()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.setup_scripts). В версии 3.7.2 это было не так. При использовании символьных ссылок будут связаны исходные исполняемые файлы.261262Также существует удобная функция уровня модуля:263264#### `venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False)`265266Создаёт экземпляр [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder) с заданными именованными аргументами и вызывает его метод [`create()`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder.create) с аргументом *env\_dir*.267268Добавлено в версии 3.3.269270Изменено в версии 3.4: Добавлен параметр *with\_pip*271272Изменено в версии 3.6: Добавлен параметр *prompt*273274Изменено в версии 3.9: Добавлен параметр *upgrade\_deps*275276## Пример расширения `EnvBuilder`277278Следующий скрипт показывает, как расширить [`EnvBuilder`](https://python-all.ru/3.12/library/venv.html#venv.EnvBuilder), реализовав подкласс, который устанавливает setuptools и pip в созданное виртуальное окружение:279280```python281import os282import os.path283from subprocess import Popen, PIPE284import sys285from threading import Thread286from urllib.parse import urlparse287from urllib.request import urlretrieve288import venv289290class ExtendedEnvBuilder(venv.EnvBuilder):291    """292    Данный построитель устанавливает setuptools и pip, чтобы с их помощью можно было293    устанавливать другие пакеты в созданное виртуальное окружение командой pip или easy_install.294295    :param nodist: Если истина, setuptools и pip не устанавливаются в296                   созданное виртуальное окружение.297    :param nopip: Если истина, pip не устанавливается в созданное298                  виртуальное окружение.299    :param progress: Если setuptools или pip устанавливаются, за ходом установки300                     можно следить, передав вызываемый объект для отслеживания прогресса.301                     Если он указан, то вызывается с двумя302                     аргументами: строкой, описывающей текущий этап, и303                     контекстом, указывающим, откуда пришла эта строка.304                     Аргумент context может принимать одно из трёх значений:305                     'main' – вызов происходит из самой virtualize(),306                     а также 'stdout' и 'stderr' – строки берутся307                     из потоков вывода подпроцесса, который308                     используется для установки приложения.309310                     Если вызываемый объект не указан, по умолчанию сведения о ходе выполнения311                     выводятся в sys.stderr.312    """313314    def __init__(self, *args, **kwargs):315        self.nodist = kwargs.pop('nodist', False)316        self.nopip = kwargs.pop('nopip', False)317        self.progress = kwargs.pop('progress', None)318        self.verbose = kwargs.pop('verbose', False)319        super().__init__(*args, **kwargs)320321    def post_setup(self, context):322        """323        Устанавливает пакеты, которые необходимо предварительно установить в создаваемое виртуальное окружение.324        создаваемое виртуальное окружение325326        обрабатываемого запроса на создание виртуального окружения327                        запрос на создание обрабатывается328        """329        os.environ['VIRTUAL_ENV'] = context.env_dir330        if not self.nodist:331            self.install_setuptools(context)332        # Читает строки из потока вывода подпроцесса и либо передаёт их вызываемому объекту для отслеживания хода выполнения333        if not self.nopip and not self.nodist:334            self.install_pip(context)335336    def reader(self, stream, context):337        """338        Читает строки из потока вывода подпроцесса и передаёт их в индикатор прогресса339        Загружает скрипт в папку с бинарными файлами виртуального окружения340        """341        progress = self.progress342        while True:343            s = stream.readline()344            if not s:345                break346            if progress is not None:347                progress(s, context)348            else:349                if not self.verbose:350                    sys.stderr.write('.')351                else:352                    sys.stderr.write(s.decode('utf-8'))353                sys.stderr.flush()354        stream.close()355356    def install_script(self, context, name, url):357        _, _, path, _, _, _ = urlparse(url)358        fn = os.path.split(path)[-1]359        binpath = context.bin_path360        distpath = os.path.join(binpath, fn)361        # Устанавливает в виртуальное окружение362        urlretrieve(url, distpath)363        progress = self.progress364        if self.verbose:365            term = '\n'366        else:367            term = ''368        if progress is not None:369            progress('Installing %s ...%s' % (name, term), 'main')370        else:371            sys.stderr.write('Installing %s ...%s' % (name, term))372            sys.stderr.flush()373        # Очистка – больше не требуется374        args = [context.env_exe, fn]375        p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)376        t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))377        t1.start()378        t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))379        t2.start()380        p.wait()381        t1.join()382        t2.join()383        if progress is not None:384            progress('done.', 'main')385        else:386            sys.stderr.write('done.\n')387        # Очищает – больше не требуется388        os.unlink(distpath)389390    def install_setuptools(self, context):391        """392        Устанавливает setuptools в виртуальное окружение393394        обрабатываемого запроса на создание виртуального окружения395                        запрос на создание обрабатывается396        """397        url = "https://bootstrap.pypa.io/ez_setup.py"398        self.install_script(context, 'setuptools', url)399        # Устанавливает pip в виртуальное окружение.400        pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')401        files = filter(pred, os.listdir(context.bin_path))402        for f in files:403            f = os.path.join(context.bin_path, f)404            os.unlink(f)405406    def install_pip(self, context):407        """408        Устанавливает pip в виртуальное окружение409410        обрабатываемого запроса на создание виртуального окружения411                        запрос на создание обрабатывается412        """413        url = 'https://bootstrap.pypa.io/get-pip.py'414        self.install_script(context, 'pip', url)415416def main(args=None):417    import argparse418419    parser = argparse.ArgumentParser(prog=__name__,420                                     description='Creates virtual Python '421                                                 'environments in one or '422                                                 'more target '423                                                 'directories.')424    parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',425                        help='A directory in which to create the '426                             'virtual environment.')427    parser.add_argument('--no-setuptools', default=False,428                        action='store_true', dest='nodist',429                        help="Don't install setuptools or pip in the "430                             "virtual environment.")431    parser.add_argument('--no-pip', default=False,432                        action='store_true', dest='nopip',433                        help="Don't install pip in the virtual "434                             "environment.")435    parser.add_argument('--system-site-packages', default=False,436                        action='store_true', dest='system_site',437                        help='Give the virtual environment access to the '438                             'system site-packages dir.')439    if os.name == 'nt':440        use_symlinks = False441    else:442        use_symlinks = True443    parser.add_argument('--symlinks', default=use_symlinks,444                        action='store_true', dest='symlinks',445                        help='Try to use symlinks rather than copies, '446                             'when symlinks are not the default for '447                             'the platform.')448    parser.add_argument('--clear', default=False, action='store_true',449                        dest='clear', help='Delete the contents of the '450                                           'virtual environment '451                                           'directory if it already '452                                           'exists, before virtual '453                                           'environment creation.')454    parser.add_argument('--upgrade', default=False, action='store_true',455                        dest='upgrade', help='Upgrade the virtual '456                                             'environment directory to '457                                             'use this version of '458                                             'Python, assuming Python '459                                             'has been upgraded '460                                             'in-place.')461    parser.add_argument('--verbose', default=False, action='store_true',462                        dest='verbose', help='Display the output '463                                             'from the scripts which '464                                             'install setuptools and pip.')465    options = parser.parse_args(args)466    if options.upgrade and options.clear:467        raise ValueError('you cannot supply --upgrade and --clear together.')468    builder = ExtendedEnvBuilder(system_site_packages=options.system_site,469                                   clear=options.clear,470                                   symlinks=options.symlinks,471                                   upgrade=options.upgrade,472                                   nodist=options.nodist,473                                   nopip=options.nopip,474                                   verbose=options.verbose)475    for d in options.dirs:476        builder.create(d)477478if __name__ == '__main__':479    rc = 1480    try:481        main()482        rc = 0483    except Exception as e:484        print('Error: %s' % e, file=sys.stderr)485    sys.exit(rc)486```487488Этот скрипт также доступен для загрузки [онлайн](https://python-all.ru/3.12/library/venv.html).489