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.xruff ставить отдельно не нужно. 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-versionuv создал структуру проекта с 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 pandasuv автоматически:
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 mycommanduv run автоматически активирует виртуальное окружение. Не нужно никаких source .venv/bin/activate.
Одноразовые скрипты
Нужно быстро запустить скрипт с зависимостями, не создавая проект?
# Запустить скрипт, который требует requests, без установки
uv run --with requests python script.py
# Запустить инструмент одноразово (npx-стиль)
uvx black .
uvx httpie https://api.github.comuvx = 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 pytest4 строки. Установка зависимостей, линтинг, форматирование, тесты. Всё.
Время 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





















