
Привет! Это Леша Жиряков, техлид 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 в проде, поделитесь своим полетом в комментариях. Пишите, какой менеджер пакетов используете вы — посмотрим, что на Хабре популярнее.
Что еще почитать:
Комментарии (13)
r2d
18.02.2025 13:12Автор, а вы можете сказать почему в кинотеатре где вы занимаетесь бэкендом нет обычных фильтров что бы можно было отфильтровать фильмы по жанру\году\стране?
f1ex0
18.02.2025 13:12poetry, uv всё это надстройки без которых можно обходиться. ориентироваться лучше на PEP 518 и PEP 621. у poetry есть существенный недостаток, он еще далек о стабильной версии и не стоит удивляться если после обновления у вас станут возникать ошибки.
По UV из статьи не понять как собирается пакет.
В целом статья с пробелами, да тема выбрана из разряда, есть плохое решение и еще одно, попробуем их сравнить по непонятным метрикам. Автору стоила заглянуть в исходники какой-либо библиотеки более или менее популярной (например fastapi, flask, numpy и т.д.), удивиться что там нет ни poetry, ни uv, изучить используемые технологии и написать хорошую статью.
kivsiak
18.02.2025 13:12https://github.com/fastapi/fastapi/blob/master/.github/workflows/test.yml
И uv и ruff в наличии, uv - это не сборщик. по крайней мере пока.
Flask уже давно не передовой с точки зрения прогресса продукт.
Numpy слишком тяжелый и специфичный проект и uv им последнюю очередь нужен.
И нет, без uv я уже жить не хочу. Это наверно лучше что было сделано для тулинга питона за последние несколько лет
Сделают еще тайпчекер внутри ruff я еще и pyright выкину.f1ex0
18.02.2025 13:12https://github.com/fastapi/fastapi/blob/master/pyproject.toml
build-backend = "pdm.backend"
CrazyOpossum
Всегда против тулз на языках, не совпадающих с целевым. Цикл отладки размыкается и разработчик лишается мгновенной обратной связи. Скорость для пакетного менеджера имеет значение только в CI/CD, это как раз горячая установка в которой отставание незначительно, и вряд ли является решающим тормозом в пайплайне. С другой стороны, разработчики на Rust не заинтересованы кровно в надёжности тулзы для разработчиков на Python, в отличие от poetry.
RH215
Никакого разделения на "разработчиков на Rust" и "разработчиков на Python" тут нет. Есть разработчики на Python и Rust. Python вообще никогда не был замкнутой на себе экосистемой.
kompilainenn2
а что там насчет NumPy и еще кучи питоновых либ, написанных на С?
CrazyOpossum
Это не тулзы. Я говорю про проекты, которые применимы сами к себе - тестовые фреймворки, линтеры, стайлеры и, да, пакетные менеджеры.
Roman_Cherkasov
У нас довольно большой проект десктопного приложения, который разбит на микросервисы (это позволяет нам разрабатывать модули и обновлять их независимо друг от друга). Изначально это был монолит, который мы успешно попилили. В процессе перехали с `pip install -r ...` на poetry. Пока модулей было 3-4 - все было нормально. Когда модулей стало 20+ резолв зависимостей время от времени начал занимать какое-то не адекватное количество времени. У нас в чате скидывали скрины с 3000+ секунд, на выполнение poetry update.
Мы некоторое время искали проблемы внутри (и они определенно были. Например бинарные файлы в репах). Исправили это. Но время на poetry update для проекта в который подключены все модули - 500-600 секунд запросто.
В тестовом формате добавили uv. Первый резолв долгий, около 120-150 секунд. Но дальше все стало сильно лучше 20-30 секунд и обновления уже загружены. И о чудо. Добавление конкретной ревизии модуля (по имени ветки или хэшу коммита) не растягивает общий резолв. Короче команда радуется, а я все ещё настороженно отношусь к продуктам с нулевой мажорной версией.
С CI\CD кстати в poetry не так больно, и разницы с uv - нет. Так как уже сформирован lock файл. Нет необходимости решать зависимости, просто берешь пакеты и устанавливаешь.
CrazyOpossum
У вас poetry update частая операция? Я тоже над немаленьким проектом работаю, но мы обновляем зависимости только по веским причинам и редко сразу несколько:
poetry lock --no-update
реагирует только на изменённые в pyproject.toml версии.Roman_Cherkasov
У разработчиков не прям чтобы частая, но вот тестеровщики - очень даже, потому что им надо тестировать модули в составе продуктов.
Roman_Cherkasov
Ещё раз обращаю внимание, что это не резолв внешних зависимостей, это модули нашего приложения. Внешние зависимости у нас тоже с фиксированными версиями и обновляются только при CVE или других критичных багфиксах
kalombo
Любой инструмент либо вызывает боль на данный момент, либо нет. Если вам норм с poetry/pip, то переходить на uv нет смысла. Если у вас есть проблемы с uv, а pip/poetry их решает, то есть смысл перейти на pip/poetry. А все эти домыслы про то, что uv испортится в будущем(потому что на расте, потому делается сторонней фирмой и т.п.) точно также применимы и к poetry и к pip, pip по сути уже "испортился". Мы не знаем, что будет завтра, возможно pip переделают и он станет самым лучшим менджером в python. Свитчится придётся всё равно рано или поздно, т.к. мир меняется и появляются новые инструменты, которые вытесняют старые.