
Привет! Это Леша Жиряков, техлид backend-команды витрины онлайн-кинотеатра KION. В прошлый раз я писал про Msgspec vs DataClasses, а сегодня поговорим о пакетных менеджерах.
В жизни каждого разработчика наступает момент, когда нужно воспользоваться сторонней библиотекой — для работы с данными или отправки запросов в БД. А после выбора библиотеки и версии — использовать менеджер пакетов. Вот какие у него функции:
установка и удаление пакетов;
обновление пакетов;
безопасность, или сравнение контрольной суммы пакета;
разрешение конфликтов версионирования в зависимостях пакетов.
В этом посте рассмотрим Poetry и UV, которые могут упростить и ускорить разработку на Python. Покажу, как устанавливать, создавать проекты, сравню производительность. Поехали!
В левом углу ринга — Poetry

Пакетный менеджер Poetry вышел в начале 2018 года благодаря разработчику Себастьяну Юстасу. Слоган проекта: «Легкое управление пакетами и зависимостями на Python». И да, главный плюс инструмента — простота.
Особенности: всестороннее определение зависимостей, изоляция от системы, интуитивные команды.
Количество звезд на GitHub: 32,4 тыс.
Открытых Issues: 472.
Версия: 2.0.1.
Год релиза: 2018.
Merge Requests (MRs): участвует главный разработчик и сообщество.
Установка
В документации нас встречает большое и красное предупреждение, что Poetry всегда нужно устанавливать в выделенной виртуальной среде. Цель — изолировать ее от остальной части системы.
Установить менеджер пакетов можно при помощи pip, pipx, curl и командой для Powershell.
Пример команды для установки:
$ pipx install poetry
Создание проекта
Проект создается при помощи команды:
$ poetry init
При выполнении команды в терминале получаем такой вывод (до двоеточия — описание, после двоеточия — значение вводит пользователь):
Package name [testpoetry]: ProjectWithPoetry
Version [0.1.0]: 0.1.1
Description []: Test project for Habr
Author [A <@gmail.com>, n to skip]: n
License []: No
Compatible Python versions [>=3.13]: >=3.9
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Каждая строка выглядит довольно просто и понятно. Можно сразу указать название, версию, описание, автора, лицензию, поддерживаемые версии Python и определить зависимости. После этого будет сгенерирован файл pyproject.toml в директории проекта.
Добавляем модули в pyproject.toml и устанавливаем при помощи poetry add:
$ poetry add fastapi
Установка из requirements.txt:
$ poetry add $(cat requirements.txt)
Еще в Poetry можно указать группу зависимостей. Например, нам нужно добавить библиотеки для разработки (black и isort) из файла requirements.dev.txt. Тогда команда получится такой:
$ poetry add --group dev $(cat requirements.dev.txt)
Теперь откроем файл pyproject.toml и изучим его содержимое:
[project]
name = "projectwithpoetry"
version = "0.1.1"
description = "Test project for Habr"
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = {text = "No"}
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
"fastapi (>=0.115.8,<0.116.0)"
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.group.dev.dependencies]
black = "^25.1.0"
isort = "^6.0.0"
Сразу видны имя проекта, версия, описания и авторы. Зависимости разделяются на основные (dependencies) и для разработки (tool.poetry.group.dev.dependencies).
В правом углу ринга — UV

Лучшее слово, которое характеризует UV, — скорость. Этот инструмент быстро устанавливает пакеты, быстро набирает звезды на GitHub, и даже его название читается быстро! Как комментирует создатель проекта Чарли Марш, причина в том, что он написан на Rust и в механизме кэширования, который оптимизирован для «теплых» операций.
Пакетный менеджер впервые предстал перед публикой в 2024 году и уже успел набрать большую популярность в среде разработки.
Особенности: в 10 раз быстрее pip и в 30 быстрее Poetry, переход между версиями Python, заменяет собой pip/pip-tools/pipx/pyenv и другие инструменты.
Количество звезд на GitHub: 37,2 тыс.
Открытых Issues: 1,1 тыс.
Версия: 0.5.24.
Год релиза: 2024.
Merge Requests (MRs): участвует главный разработчик и сообщество.
Установка
Чтобы установить UV, нужно воспользоваться командами, которые я дал выше. Но к ним добавляется еще и brew.
Самый простой способ установить UV:
$ brew install uv
В документации мы замечаем приятную вишенку на торте — образ Docker:
$ docker pull ghcr.io/astral-sh/uv:0.5.25
Создание проекта
Выполняется при помощи команды:
$ uv init
При вводе получаем:
Initialized project `testuv`
В директории проекта обнаруживаем автоматически сгенерированный файл с таким содержанием:
[project]
name = "testuv"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []
Добавляем модули в pyproject.toml и устанавливаем при помощи uv add:
$ uv add fastapi
Установка из requirements.txt:
$ uv add -r requirements.txt
Дополнительно установим зависимости для разработки в группу development из файла requirements.dev.txt. В нем указаны библиотеки black и isort.
$ uv add --dev -r requirements.dev.txt
Файл pyproject.toml:
[project]
name = "testuv"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.115.8",
]
[dependency-groups]
dev = [
"black>=25.1.0",
"isort>=6.0.0",
]
Файл pyproject.toml чуть меньше, чем аналогичный при генерации с помощью Poetry, и не содержит полей «лицензия» и «авторы». Заметно разделение зависимостей — указаны «основные» (dependencies) и «для разработки» (dev).
Чем отличаются Poetry и UV
Poetry — простой, но медленный
Как подметил в своей статье Ларри Ду, опыт использования Poetry похож на проекты Cargo и npm. Если сравнивать с pip, то Poetry предварительно пытается разрешить полный граф зависимостей DAG (англ. Directed Acyclic Graph, ориентированный ациклический граф) и устанавливает зависимости по топологической сортировке. Эта сортировка представляет собой линейное упорядочивание вершин, так что для каждого направленного ребра (u, v) вершина u предшествует вершине v.

Как conda и venv, Poetry может управлять виртуальными средами, которые находятся внутри или за пределами директории проекта. Он генерирует файлы блокировки poetry.lock, а это огромное преимущество для воспроизводимости. К тому же файлы многоплатформенные, а значит, могут быть довольно большими.
Poetry позволяет налегке разрабатывать и публиковать Python-пакеты. Это практически идеальный инструмент, но у него все-таки есть недостатки, которые могут затруднить разработку. Основное — разрешение зависимостей может быть невероятно медленным. Причина — то, как в Python-пакетах указаны зависимости. Изучение зависимостей для каждого возможного пакета в DAG может потребовать большого количества операций через загрузку и парсинг Python wheels.
Разрешаются зависимости в Poetry при помощи алгоритма поиска в глубину, написанном на Python. Для сравнения mamba использует написанные на C++ логические SAT-решатели, которые на порядок быстрее.
Устранение зависимостей для крупных проектов в Poetry в сочетании с созданием многоплатформенных файлов блокировки может занять довольно много времени, особенно при наличии реального конфликта в DAG.
UV — быстрый, но только набирающий обороты
Это многообещающий инструмент управления пакетами в экосистеме Python. Проект призван стать заменой pip и дополнением к Python. Сейчас API нестабильно — на это указывает мажорная версия проекта, которая начинается с 0. Примечательно, что разработка ведется при поддержке компании Astral.sh, основанной Чарли Маршем и создателями линтера ruff — инструмента, который практически в одночасье вытеснил всех конкурентов, когда был выпущен в 2022 году.
UV, как и Poetry, поддерживает pyproject.toml и, как и pip, использует алгоритм обратного отслеживания для разрешения зависимостей. Но есть одно отличие — в UV алгоритм написан на Rust, чем и обосновывается его быстрая скорость работы. Когда дело доходит до разрешения зависимостей, то UV работает быстрее, чем Poetry.
Сравнение производительности
Немного о бенчмарках
Из документации UV — все тесты были рассчитаны на macOS с использованием Python 3.12.4 (для инструментов, отличных от UV) и содержат несколько важных предостережений:
Производительность тестов может сильно различаться в зависимости от различных операционных и файловых систем. Дело в том, что UV использует разные стратегии установки, основываясь на возможностях файловой системы.
Так, в macOS используется рефлинкинг, а в Linux — хардлинкинг.Производительность тестов может сильно различаться в зависимости от устанавливаемых пакетов.
Дальше рассмотрим тесты на примере пакета Trio и его зависимостей, которые указаны в docs-requirements.in.
«Горячая» установка
Сравнительный анализ установки пакета (команда uv sync) с использованием «теплого» кэша. Эквивалентно удалению и повторному созданию виртуальной среды, а затем заполнению ее зависимостями, которые были раньше установлены на том же компьютере.

На графике видно, что UV в разы обгоняет своих конкурентов — PDM, Poetry и pip-sync. Poetry занимает второе место.
«Холодная» установка
Анализ установки пакетов с использованием «холодного» кэша. Равно выполнению команды uv sync на новом компьютере или в CI (предполагается, что кэш менеджера пакетов — не общий для всех запусков).

UV занимает первое место по скорости выполнения, но отставание других пакетных менеджеров намного меньше, чем в тесте выше.
«Теплое» разрешение зависимостей
Тест на разрешение зависимостей (uv lock) с помощью «теплого» кэша, но без существующего файла блокировки (uv.lock). Равнозначно удалению requirements.txt для его генерации из файла requirements.in.

Тут и нечего говорить: UV лидирует.
«Холодное» разрешение зависимостей
Сравнение разрешения зависимостей с помощью холодного кэша. Соответствует запуску uv lock на новом компьютере или в CI — при условии, что кэш менеджера пакетов не используется совместно для всех запусков.

UV справился менее чем за 0,5 секунды, когда его коллеги по цеху — за 3 и более секунд.
Что в итоге
Подытожим сравнительной таблицей:
Параметр | Poetry | Uv |
Год появления | 2018 | 2024 |
Версия Python | 3.9-3.13 | 3.8-3.13 |
Текущий релиз | 2.0.1 | 0.5.25 |
Лицензия | MIT | Apache-2.0 или MIT |
ЯП проекта | Python | Rust |
Кол-во контрибьюторов | 581 | 304 |
Кол-во звезд | 32,5 тыс. | 37,6 тыс. |
Первое, что бросается в глаза, — это скорость работы UV. Кто бы что ни говорил, он все равно очень быстрый. Благодарить можно как разработчиков, так и то, что проект написан на Rust. Только в одном тест-кейсе, когда проводилась «холодная» установка, Poetry приближался к UV. В остальных случаях UV — безусловный лидер.
Как и в прошлом моем посте про сравнение FastAPI и Litestar, важно подчеркнуть различие версий у Poetry и UV. Первый проект начал разрабатываться в далеком 2018 году, и текущий релиз начинается с 2.0 — это говорит о стабильности продукта. UV появился в 2024 и до сих пор движется к первому крупному релизу. Пока же его версия 0.5 — а это не гарантирует бесперебойной работы в продакшне.
UV дополнительно поддерживает версию Python 3.8. Пункт может быть важен для команд, которые сейчас разрабатывают решения на этой версии языка программирования.
Лицензия проекта Poetry — MIT. У UV ее можно выбрать — MIT или Apache-2.0.
Инициализация проекта при помощи Poetry более user-friendly и позволяет сразу указать описание проекта, его авторов, поддерживаемые версии Python и лицензию. В этом плане UV более минималистичен, но приходится вручную открывать и редактировать pyproject.toml.
Кто уже использует UV в проде, поделитесь своим полетом в комментариях. Пишите, какой менеджер пакетов используете вы — посмотрим, что на Хабре популярнее.
Что еще почитать: