Процесс управления зависимостями в 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. Он упрощает процесс определения метаданных и зависимостей, а также гарантирует возможность воспроизведения проекта другими разработчиками.
Читайте также:
- Разработка продвинутого GUI на Python
- Написание консольных скриптов: Bash против Python
- Как автоматизировать удаление ненужных файлов с помощью Python
Читайте нас в Telegram, VK и Дзен
Перевод статьи Giorgos Myrianthous: What is pyproject.toml in Python