pip install, requirements.txt, virtualenv, black, isort, flake8, mypy, setup.py... Если вы настраиваете Python-проект так же, как в 2020 году, эта статья для вас. Показываю современный стек, который заменяет всё вышеперечисленное.
В 2026 году экосистема Python-инструментов наконец собралась в нечто цельное. Два инструмента (uv и ruff) + один файл (pyproject.toml) заменяют 7+ отдельных утилит. Вот как это работает.
Что заменяем и на что
Было |
Стало |
|---|---|
pip + pip-tools |
uv |
virtualenv / venv |
uv |
pyenv |
uv |
poetry / pipenv |
uv |
black (форматирование) |
ruff format |
isort (сортировка импортов) |
ruff |
flake8 (линтинг) |
ruff check |
setup.py / setup.cfg |
pyproject.toml |
requirements.txt |
pyproject.toml + uv.lock |
Два инструмента вместо девяти. Оба написаны на Rust, оба от Astral. Работают в 10-100 раз быстрее аналогов на Python.
Шаг 1. Установка uv
Одна команда:
# macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" # Или через pip (если хочется по-старому) pip install uv
Проверяем:
$ uv --version uv 0.7.x
ruff ставить отдельно не нужно. uv умеет запускать его через uvx ruff. Но если хотите глобально:
uv tool install ruff
Шаг 2. Создаём проект
$ uv init myproject Initialized project `myproject` at `./myproject` $ cd myproject $ ls pyproject.toml src/ README.md .python-version
uv создал структуру проекта с pyproject.toml, папку src/ и файл .python-version. Никаких setup.py, requirements.txt, Makefile.
Если нужен Python конкретной версии:
# uv сам скачает и установит нужную версию Python uv python install 3.13 uv python pin 3.13
Да, uv заменяет pyenv. Он сам управляет версиями Python.
Шаг 3. Зависимости
Забудьте pip install. Теперь так:
# Добавить зависимость uv add requests uv add pandas numpy # Добавить dev-зависимость uv add --dev pytest ruff # Удалить зависимость uv remove pandas
uv автоматически:
1. Создаёт виртуальное окружение (если его нет).
2. Добавляет пакет в pyproject.toml.
3. Обновляет lock-файл uv.lock.
4. Устанавливает пакет.
Всё за одну команду. Никаких pip freeze > requirements.txt.
Скорость
uv устанавливает пакеты в 10-100 раз быстрее pip. Холодная установка numpy + pandas + requests:
Инструмент |
Время |
|---|---|
pip |
~12 сек |
poetry |
~8 сек |
uv |
~0.5 сек |
Это не опечатка. uv кэширует пакеты глобально и использует жёсткие ссылки вместо копирования файлов.
Шаг 4. pyproject.toml
Вот как выглядит типичный pyproject.toml после настройки:
[project] name = "myproject" version = "0.1.0" description = "My awesome project" readme = "README.md" requires-python = ">=3.12" dependencies = [ "requests>=2.32", "numpy>=2.0", ] [dependency-groups] dev = [ "pytest>=8.0", "ruff>=0.9", ] [tool.ruff] target-version = "py312" line-length = 88 [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "UP", # pyupgrade "B", # flake8-bugbear "SIM", # flake8-simplify ] [tool.ruff.format] quote-style = "double" [tool.pytest.ini_options] testpaths = ["tests"]
Один файл. Зависимости, линтер, форматтер, тесты. Всё здесь.
Шаг 5. Линтинг и форматирование (ruff)
ruff заменяет flake8 + black + isort + pyupgrade. Одна команда вместо четырёх.
# Проверить код uvx ruff check . # Проверить и автоматически исправить uvx ruff check --fix . # Отформатировать код (замена black) uvx ruff format . # Проверить форматирование без изменений uvx ruff format --check .
Скорость ruff
ruff проверяет код в 10-100 раз быстрее flake8. На проекте из 1000 файлов:
Инструмент |
Время |
|---|---|
flake8 |
~12 сек |
flake8 + isort + black |
~25 сек |
ruff check + ruff format |
~0.3 сек |
Пример: что ruff ловит
# До import os import sys from typing import Optional, List, Dict import json def process(data: Optional[List[Dict[str, str]]] = None): if data == None: data = list() for item in data: if len(item.keys()) > 0: print(item)
# После ruff check --fix + ruff format import json def process(data: list[dict[str, str]] | None = None): if data is None: data = [] for item in data: if item: print(item)
Что ruff сделал:
1. Убрал неиспользуемые импорты (os, sys).
2. Отсортировал оставшиеся импорты.
3. Заменил Optional[List[Dict]] на list[dict] | None (Python 3.10+).
4. Заменил == None на is None.
5. Заменил list() на [].
6. Упростил len(item.keys()) > 0 до item.
Шаг 6. Запуск скриптов
Для запуска скриптов внутри виртуального окружения:
# Запуск скрипта uv run python src/myproject/main.py # Запуск тестов uv run pytest # Запуск любой команды в окружении uv run mycommand
uv run автоматически активирует виртуальное окружение. Не нужно никаких source .venv/bin/activate.
Одноразовые скрипты
Нужно быстро запустить скрипт с зависимостями, не создавая проект?
# Запустить скрипт, который требует requests, без установки uv run --with requests python script.py # Запустить инструмент одноразово (npx-стиль) uvx black . uvx httpie https://api.github.com
uvx = npx для Python. Скачивает, запускает, не засоряет систему.
Шаг 7. CI/CD
Минимальный GitHub Actions workflow:
# .github/workflows/ci.yml name: CI on: [push, pull_request] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - run: uv sync - run: uvx ruff check . - run: uvx ruff format --check . - run: uv run pytest
4 строки. Установка зависимостей, линтинг, форматирование, тесты. Всё.
Время CI на типичном проекте:
Стек |
Время |
|---|---|
pip + flake8 + black + pytest |
~45 сек |
poetry + flake8 + black + pytest |
~60 сек |
uv + ruff + pytest |
~12 сек |
Шаг 8. Docker
Минимальный Dockerfile:
FROM python:3.13-slim # Установить uv COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv # Копировать файлы проекта WORKDIR /app COPY pyproject.toml uv.lock ./ # Установить зависимости (кэшируется Docker layer) RUN uv sync --no-dev --frozen # Копировать код COPY src/ src/ CMD ["uv", "run", "python", "-m", "myproject"]
Важный момент: pyproject.toml и uv.lock копируются отдельно от кода. Это позволяет Docker кэшировать слой с зависимостями. Если код изменился, а зависимости нет, переустановки не будет.
Миграция с pip/poetry за 2 минуты
С requirements.txt
# Инициализировать проект uv init # Импортировать зависимости из requirements.txt uv add $(cat requirements.txt)
С poetry
uv понимает pyproject.toml в формате Poetry. Просто:
# Удалить poetry.lock, создать uv.lock rm poetry.lock uv lock uv sync
Если в pyproject.toml есть секция [tool.poetry], uv прочитает зависимости оттуда.
Полный чеклист нового проекта
# 1. Создать проект uv init myproject && cd myproject # 2. Добавить зависимости uv add requests pydantic # 3. Добавить dev-зависимости uv add --dev pytest ruff # 4. Написать код # ... # 5. Проверить и отформатировать uvx ruff check --fix . uvx ruff format . # 6. Запустить тесты uv run pytest # 7. Готово
Пять минут. Никаких setup.py, MANIFEST.in, requirements.txt, tox.ini, .flake8, .isort.cfg, pyproject.toml на 200 строк.
uv + ruff + pyproject.toml = всё, что нужно для Python-проекта в 2026 году.
Ссылки
uv на GitHub (80k+ звёзд)
ruff на GitHub (40k+ звёзд)
Документация uv
Документация ruff
PEP 621: стандарт pyproject.toml
Комментарии (6)

avasiukevich
07.06.2026 11:52Хороший гайд!
Недавно пришлось с нуля создавать новый проект на питоне (впервые за много лет), почти все также в итоге настроил
Я бы еще добавил в базовую конфигурацию проекта:
скрипт первичной настройки для новых разработчиков (сильно упрощает онбординг)
настройку типичных команд и сценариев в just / make (так как uv это все же не lifecycle manager)
проверку типизации (mypy)
набор pre-commit хуков (проверить форматирование, консистентность окружения, мелкие типичные проблемы, и т д)

orki
07.06.2026 11:52Пять минут. Никаких
setup.py,MANIFEST.in,requirements.txt,tox.ini,.flake8,.isort.cfg,pyproject.tomlна 200 строк.про pyproject.toml -
наглая ложьне соответствует реалиям. Все настройки ruff, pytest, mypy или pyright - все будет в нём, если у вас не одноразовый проект (но тогда и ci cd вам не нужен как таковой)
Но в целом ок, помимо тестов и проверки типов через mypy или pyright, я бы добавил еше проверку пакетов на уязвимости через uv audit

ophil
07.06.2026 11:52если уж тул на раст, то установка `cargo -v install uv`, можно заодно и `cargo -v install just`
rSedoy
вот не люблю такие заявления, всё описанное тут было актуальным и в 2025 году, да и uv 0.7.x намекает на прошлый год.