🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.

#1
open+1121proposed by gardener · Aug 4, 2026 · based on v1
Result · becomes v2
1
Проверить установку uv

Выполняй команду во встроенном терминале VS Code, находясь в папке будущего проекта. Если команда не найдена, сначала установи uv и заново открой терминал.

Why: Все последующие операции выполняются через uv, поэтому проблему с установкой лучше обнаружить сразу.
code
1uv --version
  • Команда напечатала версию uv
  • Терминал открыт в нужной папке
  • После установки uv команда доступна в новом терминале
2
Создать пакетный проект

Точка в конце означает «в текущей папке». Флаг --package создаёт устанавливаемый проект с разделом [build-system], необходимым для собственных команд. После запуска проверь pyproject.toml, README.md, .python-version, .gitignore и папку src/ с пакетом.

Why: Точки входа из `[project.scripts]` работают после установки проекта как пакета, а не как простого набора скриптов.
code
1uv init --package .
  • В папке появился pyproject.toml
  • В pyproject.toml есть раздел [build-system]
  • Появилась папка src с пакетом
3
Закрепить Python 3.12

После команды открой .python-version: там должна быть строка 3.12. В pyproject.toml установи requires-python = ">=3.12"; это минимальная поддерживаемая версия, тогда как .python-version задаёт версию по умолчанию для работы с проектом.

Why: Явная версия по умолчанию уменьшает расхождения между локальными окружениями и не даёт случайно запустить проект на слишком старом Python.
code
1uv python pin 3.12
  • Файл .python-version содержит 3.12
  • В pyproject.toml указано requires-python = ">=3.12"
  • Команда uv run python --version показывает Python 3.12
4
Перенести пакеты в корень

Перенеси созданный пакет из src/<имя_проекта>/ в корневую папку app/, затем удали пустую src. Сразу создай папку scripts/ с пустым __init__.py и добавь перед [build-system] настройку сборщика:

toml
1[tool.hatch.build.targets.wheel]
2packages = ["app", "scripts"]
Why: После переноса сборщику нужно явно указать новые пути пакетов, иначе установка проекта завершится ошибкой или не включит нужный код.
  • Папка app находится в корне проекта
  • Папка scripts содержит __init__.py
  • В настройках wheel перечислены app и scripts
5
Добавить рабочие зависимости

Команда добавит FastAPI и Uvicorn в dependencies, создаст или обновит uv.lock и синхронизирует .venv. Не копируй версии из примеров: проверь ограничения, которые uv записал для актуальных установленных выпусков.

Why: В `pyproject.toml` перечислены прямые требования проекта, а `uv.lock` фиксирует разрешённое дерево прямых и транзитивных зависимостей.
code
1uv add fastapi uvicorn
  • В dependencies появились fastapi и uvicorn
  • Созданы uv.lock и .venv
  • Команда uv lock --check завершается успешно
6
Проверить окружение проекта

Команда должна импортировать FastAPI из окружения проекта и напечатать его версию. Для сравнения можно выполнить ту же проверку без uv run, но результат будет зависеть от Python, который первым найден в PATH.

Why: `uv run` синхронизирует окружение проекта и запускает команду с его интерпретатором и зависимостями.
code
1uv run python -c "import fastapi; print(fastapi.__version__)"
  • Команда напечатала версию fastapi
  • uv run python --version соответствует закреплённой версии
  • Импорт завершается без ModuleNotFoundError
7
Добавить Ruff для разработки

Флаг --dev помещает Ruff в группу [dependency-groups].dev, а не в основные dependencies. Проверь актуальное ограничение версии, которое uv записал в pyproject.toml.

Why: Отдельная группа не смешивает инструменты проверки кода с библиотеками, необходимыми приложению во время работы.
code
1uv add --dev ruff
  • ruff находится в группе dev
  • ruff отсутствует в основных dependencies
  • Команда uv run ruff --version печатает версию
8
Создать и объявить команду lint

Создай scripts/commands.py:

python
1"""Команды проекта, объявленные в pyproject.toml."""
2
3import subprocess
4import sys
5
6
7def lint() -> None:
8 """Проверить код линтером."""
9 result = subprocess.run(["ruff", "check", "."], check=False)
10 sys.exit(result.returncode)

Затем добавь или обнови раздел:

toml
1[project.scripts]
2lint = "scripts.commands:lint"

Слева указано имя команды, справа — путь в формате модуль:функция.

Why: Проброс кода возврата через `sys.exit` позволяет терминалу и CI отличить успешную проверку от найденных ошибок.
  • Создан файл scripts/commands.py
  • В [project.scripts] объявлена команда lint
  • Функция завершается кодом Ruff через sys.exit
9
Запустить команду lint

При первом запуске uv может переустановить сам проект в окружение — это нормально. Если появляется Failed to spawn: lint, проверь наличие [build-system], запись в [project.scripts] и включение scripts в настройки wheel.

Why: Этот запуск одновременно проверяет сборку пакета, установку точки входа и доступность Ruff в окружении разработки.
code
1uv run lint
  • Команда запускается под именем lint
  • Ruff печатает результат проверки
  • При ошибках команда возвращает ненулевой код
10
Проверить путь импортируемой команды

Команда печатает файл, из которого Python действительно импортирует модуль. Ожидается путь к scripts/commands.py; рядом не должно быть одноимённых файла и папки, способных запутать импорт.

Why: Проверка обнаруживает затенение модулей, при котором Python выполняет не тот код, который разработчик редактирует.
code
1uv run python -c "import importlib.util as u; print(u.find_spec('scripts.commands').origin)"
  • Напечатан путь к scripts/commands.py
  • В scripts нет одноимённых файла и папки
  • Путь относится к текущему проекту
11
Проверить файлы для коммита

Убедись, что .gitignore содержит .venv/, __pycache__/, *.py[cod] и .env, но не содержит uv.lock. В Git должны попасть pyproject.toml, uv.lock, .python-version, .gitignore, app/ и scripts/; если .venv уже отслеживается, удали её только из индекса командой git rm -r --cached .venv.

Why: Lock-файл обеспечивает воспроизводимость, а локальное окружение и секреты не должны раздувать репозиторий или попадать в его историю.
code
1git status --short && git check-ignore .venv
  • git check-ignore подтверждает игнорирование .venv
  • uv.lock и .python-version видны среди новых файлов
  • В списке нет .env, __pycache__ и содержимого .venv