Shanraq.org Shanraq.org
Зависимости: повторяемое окружение вместо «у меня работает»
IT

Python: от данных до своей сводки Урок 55 из 56

Зависимости: повторяемое окружение вместо «у меня работает»

Пятьдесят четвёртый урок курса по Python. Отделяем прямые зависимости от полного lock-файла, фиксируем версию Python и собираем чистое окружение, которое можно воспроизвести через год.

Зачем это нужно

pip install pandas сегодня и через год может установить разные версии pandas и её зависимостей. Код не менялся, а вывод или даже API изменились. Воспроизводимость означает: известны версия Python, точные версии всех пакетов и команда проверки с нуля.

Два списка с разными задачами

В requirements.in человек записывает только прямые зависимости:

pandas>=3.0,<3.1
matplotlib>=3.11,<3.12
jsonschema>=4.26,<5

Из него инструмент создаёт requirements.txt — полный снимок с точными версиями прямых и транзитивных пакетов:

python -m pip install pip-tools==7.6.1
python -m piptools compile --generate-hashes requirements.in
python -m piptools sync requirements.txt

Оба файла хранятся в Git. Первый объясняет намерение обновления, второй повторяет конкретную сборку. Хэши защищают от незаметной подмены файла пакета, но не доказывают, что сам пакет безопасен.

Версия Python тоже зависимость

Создайте .python-version:

3.14

И запишите поддерживаемый диапазон в pyproject.toml:

[project]
requires-python = ">=3.12,<3.15"

Первое значение выбирает среду проекта, второе описывает обещанный диапазон. CI обязан проверить этот диапазон. Не пишите точный patch-релиз в requires-python, если проект действительно работает на совместимых исправлениях Python.

Проверка в чистой среде

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install --require-hashes -r requirements.txt
python -m pytest -q
python -m mypy --strict sholu main.py
python main.py --offline --dry-run

На Windows команда активации другая: .venv\Scripts\activate. Надёжная инструкция всегда использует python -m pip, чтобы пакет устанавливался в выбранный интерпретатор.

Что показывает pip freeze

python -m pip freeze

pip freeze печатает то, что уже установлено. Это полезная диагностика и способ получить первый снимок из нового чистого окружения. В старом рабочем окружении команда может записать случайные инструменты автора и не объясняет, какие зависимости прямые. Поэтому не заменяйте ею осмысленный requirements.in.

Обновление — отдельная работа

Обновляйте lock-файл осознанно: измените допустимый диапазон, пересоберите его, прочитайте изменения, запустите тесты и только затем сохраняйте. Не смешивайте обновление зависимостей с функциональной правкой — иначе причину сбоя труднее найти.

Не храните токены и пароли в requirements.txt, адресах Git или .env.example. Секреты поступают из локальной среды или хранилища CI.

Карта урока

Карта урока: намерение, lock-файл и чистая сборка

Опорный сигнал: Python + requirements.in → lock с хэшами → чистая среда → тесты.

Скажите своими словами

  1. Чем requirements.in отличается от requirements.txt?
  2. Почему одной фиксации прямых пакетов недостаточно?
  3. Что на самом деле показывает pip freeze?
  4. Зачем собирать проект в чистой среде?

Разминка

1. Предскажите. Какая запись точнее воспроизводит сборку?

choices = ["pandas", "pandas>=3", "pandas==3.0.5"]
print(choices[-1])

2. Заполните модульный запуск.

python ... pip freeze

3. Исправьте процесс. Разработчик обновил lock-файл, но не запустил тесты.

Задание

Обязательное. Создайте чистое окружение, requirements.in, lock-файл с хэшами и .python-version. Установите зависимости с --require-hashes, затем выполните тесты и mypy.

environment: reproducible
tests: passed
types: passed

На своём проекте. Сравните pip freeze старой и чистой среды и объясните лишние строки.

По желанию. Настройте автоматическое предложение обновлений, но оставьте слияние только после тестов и просмотра diff.

Куда это встанет в проекте

Шаг 29 получает входной список, lock-файл, версию Python и единый сценарий проверки. В финальном уроке этот проверенный снимок станет публикуемым артефактом.

Ответы

Показать ответы
  1. .in хранит прямое намерение, .txt — точный полный граф.
  2. Транзитивная зависимость тоже может изменить поведение.
  3. Состояние текущего окружения, а не замысел проекта.
  4. Чтобы обнаружить неявные пакеты и зависимость от компьютера автора.
pandas==3.0.5
  1. Пропуск — -m.
command = "python -m pip freeze"
print(command)
python -m pip freeze
  1. После пересборки lock-файла выполните установку в чистой среде, тесты, mypy и offline smoke-test.
checks = ["install", "pytest", "mypy", "offline"]
print(" -> ".join(checks))
install -> pytest -> mypy -> offline

Источники

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Проверить задание

Сначала решите и запустите в VS Code — редактор покажет ошибку на месте. Готовое решение вставьте сюда. Проверяет модель: она укажет на ошибку, но не даст готовый ответ.

Чтобы проверить, нужно войти. Войти

Комментарии (0)

Пока нет комментариев. Будьте первым.