Процесс управления зависимостями в Python вызывает сложности, а иногда и откровенное раздражение. Новичкам хочется даже в одной виртуальной среде установить любую потенциально полезную зависимость, т.е. пакет. Подобная тенденция увеличивает вероятность появления конфликтующих зависимостей пакетов и в результате приводит к такому явлению, как ад зависимостей

Файлы setup.py, setup.cfg и requirements.txt позволяют по-разному работать с зависимостями в проектах Python. Однако в Python 3.6 был представлен новый стандартный файл конфигурации pyproject.toml, который упрощает пользователям управление зависимостями и определениями метаданных.

За последние годы файл pyproject.toml обрел популярность и стал востребованным для управления зависимостями в проектах Python. В статье мы рассмотрим его практическое применение и покажем, как установить проект со спецификацией pyproject.toml в режиме редактирования. 

Управление зависимостями до pyproject.toml

Сначала в Python для создания дистрибутивов применялся пакет distutils. Затем появился setuptools, который представлял собой надстройку над distutils. Оба инструмента задействовали файл setup.py, в котором пользователи определяли зависимости и метаданные, используемые как часть дистрибутива для сборки пакета. 

Однако это породило проблему, поскольку любой проект, выбирающий для работы setuptools, должен импортировать пакет в файл setup.py. Следовательно, setup.py не может выполняться без знания своих зависимостей, но при этом он предназначен для определения этих зависимостей. Вот мы и пришли к так называемой проблеме курицы и яйца в управлении зависимостями Python. 

Все выше сказанное хорошо объясняет возникшую потребность в новом подходе. Более подробный разбор сути проблемы курицы и яйца в отношении setuptools и pip содержится в PEP-518.

Новое предложение, которое является частью PEP-518, позволяет проектам Python предварительно указывать свои зависимости. В этом случае такие инструменты, как pip, получают возможность проверить факт их установки до начала сборки проекта. 

Файл pyproject.toml

Файл pyproject.tom был представлен как часть предложения по улучшению PEP 518. Он определяет, как именно проекты Python должны указывать зависимости сборки. 

Эти зависимости хранятся в файле, который находится в корневой директории проекта и соответствует синтаксису TOML

Он содержит метаданные, такие как имя проекта, версию, описание, автора, лицензию и другую информацию. 

Одна из ключевых характеристик файла pyproject.toml —  способность определять зависимости проекта. Разработчики могут указывать пакеты и версии, необходимые для правильного запуска проекта. pyproject.toml обеспечивает согласованность проекта и гарантирует возможность его воспроизведения другими разработчиками. 

Файл pyproject.toml также поддерживает концепцию extras, позволяющую разработчикам определять дополнительные зависимости. Пользователи могут устанавливать только нужные зависимости для запуска проекта. Как правило, в разделе extras указываются дополнительные требования, которые используются в рамках тестирования, например pytest

Помимо стандартных метаданных и зависимостей файл pyproject.toml также поддерживает настраиваемые поля с возможностью их применения сторонними инструментами. Это могут быть статические анализаторы, средства форматирования и проверки, такие как black и mypy. Данное свойство файла pyproject.toml позволяет разработчикам расширять функциональность файла и добавлять настраиваемые поля в соответствии с требованиями. 

Управление зависимостями в pyproject.toml

pyprojet.toml можно задействовать с инструментами управления зависимостями пакетов, такими как setuptools и poetry.

В качестве примера рассмотрим файл для проекта, который использует poetry:

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "my-project"
version = "1.0.0"
description = "My Python project"
authors = ["John Doe <[email protected]>"]
license = "MIT"

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.dev-dependencies]
pytest = "^4.6"

[tool.poetry.extras]
docs = ["sphinx"]

Пример с setuptools:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "my_package"
description = "My package description"
readme = "README.rst"
requires-python = ">=3.7"
keywords = ["one", "two"]
license = {text = "BSD 3-Clause License"}
classifiers = [
"Framework :: Django",
"Programming Language :: Python :: 3",
]
dependencies = [
"requests",
'importlib-metadata; python_version<"3.8"',
]
dynamic = ["version"]

[project.optional-dependencies]
pdf = ["ReportLab>=1.2", "RXP"]
rest = ["docutils>=0.3", "pack ==1.1, ==1.3"]

[project.scripts]
my-script = "my_package.module:function"

Установка проекта в режиме редактирования из pyproject.toml

Если вы активно разрабатываете проект, то, скорее всего, захотите установить его локально в режиме редактирования. При установке пакета в режиме редактирования из определенного места любые изменения исходного кода сразу же отражаются в среде (без необходимости переустановки “новой” версии).

Предположим, вы управляете зависимостями Python с помощью poetry. Чтобы установить проект Python в режиме редактирования, файл pyproject.toml должен содержать следующее: 

[build-system]
requires = ["poetry-core>=1.0.8"]
build-backend = "poetry.core.masonry.api"

Из корневой директории проекта просто выполняем команду: 

$ pip install -e .

Как вариант, poetry install также устанавливает режим редактирования. 

Заключение 

В статье мы рассмотрели практическое применение pyproject.toml в Python, когда дело касается управления зависимостями и распространения проектов между участниками сообщества. 

В целом, pyproject.toml предоставляет стандартную и простую конфигурацию для проектов Python. Он упрощает процесс определения метаданных и зависимостей, а также гарантирует возможность воспроизведения проекта другими разработчиками. 

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Giorgos Myrianthous: What is pyproject.toml in Python

Предыдущая статьяСообщество  —  лучший двигатель карьеры разработчика
Следующая статья5 ведущих веб-фреймворков 2023 года