Использование setuptools для управления зависимостями и распространения пакетов Python

Введение

В одной из своих недавних статей я обсуждал разницу между файлами requirements.txt и setup.py, которая в конечном итоге может помочь разработчикам управлять зависимостями своих пакетов таким образом, чтобы им было легко их распространять.

В сегодняшней статье я сосредоточусь на пакете setuptools и расскажу о разнице между файлами setup.py и setup.cfg. Кроме того, мы также обсудим, как эти файлы могут понимать requirements.txt файл, который должен содержать список зависимостей.

Наконец, мы также обсудим назначение файла pyproject.toml и то, как изменился ландшафт распространения пакетов после принятия PEP-517. Мы также продемонстрируем, как перейти к использованию pyproject.toml с setuptools таким образом, чтобы вы соответствовали требованиям PEP-517 и PEP-518.

инструменты настройки в Python

setuptools — это библиотека, построенная поверх distutils, которая устарела (и подлежит удалению с Python 3.12). Пакет предлагает широкий спектр функций, которые упрощают упаковку проектов Python, что представляет собой процесс, который постоянно развивается и иногда может быть довольно сложным.

Под упаковкой мы обычно подразумеваем как зависимость управление, так и пакет распространение. Другими словами, упаковка — это обработка зависимостей ваших проектов (и даже зависимостей зависимостей и т. д.), а также то, как распространять ваш пакет, чтобы сделать его широко доступным и пригодным для использования другими проектами.

Файл setup.py

Файл setup.py, вероятно, является наиболее важным файлом, который должен быть включен в корневой каталог вашего проекта Python, и в основном он служит двум основным целям:

  1. Он содержит различную информацию, относящуюся к вашему пакету, включая параметры и метаданные, такие как имя пакета, версия, автор, лицензия, минимальные зависимости, точки входа, файлы данных и многое другое.
  2. Служит интерфейсом командной строки, позволяющим выполнять команды упаковки.

Пример файла setup.py

# setup.py placed at root directory
from setuptools import setup
setup(
    name='examplepackage'
    version='1.0.1',
    author='Giorgos Myrianthous',
    description='This is an example project',
    long_description='This is a longer description for the project',
    url='https://medium.com/@gmyrianthous',
    keywords='sample, example, setuptools',
    python_requires='>=3.7, <4',
    install_requires=['pandas'],
    extras_require={
        'test': ['pytest', 'coverage'],
    },
    package_data={
        'sample': ['example_data.csv'],
    },
    entry_points={
        'runners': [
            'sample=sample:main',
        ]
    }
)

А вот объяснение ключевых слов, которые использовались при вызове метода setup():

  • name: это строка, соответствующая имени пакета
  • version: строка, соответствующая номеру версии пакета.
  • author: указывает автора (авторов) пакета.
  • description: Это строка для краткого описания пакета (обычно однострочное описание).
  • long_description: строка для более подробного описания пакета.
  • url: строка, указывающая URL-адрес пакета (обычно это репозиторий GitHub или страница PyPI).
  • keywords: это строка, разделенная запятыми (также может быть списком строк), которая содержит некоторые ключевые слова, относящиеся к пакету.
  • python_requires: это строка с разделителями-запятыми, которая содержит спецификаторы версии для версии Python, поддерживаемой пакетом.
  • install_requires: список строк, содержащих минимальные зависимости, необходимые для успешного запуска пакета.
  • extras_require: словарь, в котором ключи соответствуют именам дополнительных режимов, а значения представляют собой списки, содержащие минимальные требуемые зависимости. Например, дополнительным режимом может быть test, где список зависимостей должен включать все дополнительные пакеты, необходимые для выполнения тестов, определенных в пакете.
  • package_data: Это словарь, где ключи — это имена пакетов, а значения — это списки шаблонов глобусов.
  • entry_points: Это словарь, в котором ключи соответствуют именам точек входа и значениям фактических точек входа, определенных в исходном коде.

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

Файл setup.cfg

Традиционно файл setup.py использовался для сборки пакетов, например. с помощью команды build через интерфейс командной строки.

$ python setup.py build

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

setup.cfg – это ini-файл, содержащий параметры по умолчанию для setup.py команд. Вы можете в значительной степени указать каждое ключевое слово, которое мы использовали в файле setup.py, в новом файле setup.cfg и просто использовать файл setup.py в качестве интерфейса командной строки.

Пример файла setup.cfg

# setup.cfg file at the root directory
[metadata]
name = examplepackage
version = 1.0.1
author = Giorgos Myrianthous
description = This is an example project
long_description = This is a longer description for the project
url = https://medium.com/@gmyrianthous
keywords = sample, example, setuptools
[options]
python_requires = >=3.7, <4
install_requires = 
    pandas
[options.extras_require]
test = 
    pytest
    coverage
[options.package_data]
sample = 
    example_data.csv'

setup.py с setup.cfg

Теперь, предположив, что вы переместили все параметры в файл setup.cfg, как описано в предыдущем разделе, теперь вы можете создать фиктивный файл setup.py, который будет просто вызывать метод setup():

from setuptools import setup
if __name__ == '__main__':
    setup()

Более подробные примеры того, как использовать файлы setup.py и setup.cfg, можно найти в примере проекта PyPA на GitHub.

Файл pyproject.toml и переход на PEP-517

Начиная с PEP-517 и PEP-518 setuptools больше не является де-факто инструментом, который предполагается использовать при упаковке проектов Python. Согласно спецификации PEP-518, системные зависимости сборки для проекта Python должны быть включены в файл с именем pyproject.toml, соответствующий формату TOML.

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

Предполагается, что файл pyproject.toml решает проблему зависимости инструмента сборки от курицы и яйца, поскольку сам pip может читать pyproject.yoml вместе с версией setuptools или wheel, необходимой для проекта. Файл ожидает таблицу [build-system], которая используется для хранения информации, связанной со сборкой.

Теперь давайте сложим кусочки головоломки вместе. Если вы хотите использовать setuptools, теперь вам нужно указать файл pyproject.toml с содержимым, показанным ниже:

# pyproject.toml file specified at the root of the directory
[build-system]
requires = ["setuptools>=42", "wheel"]   # PEP 508 specifications.
build-backend = "setuptools.build_meta"

Затем вам также необходимо указать файл setup.py или setup.cfg, как мы показали в предыдущих разделах руководства. Обратите внимание, что я лично предпочитаю последнее обозначение.

Наконец, вы можете создать свой проект с помощью компоновщика, такого как сборка PyPA, которую вы можете получить через pip (pip install build) и, наконец, вызвать компоновщик.

$ python3 -m build

И вуаля! Теперь ваш дистрибутив будет готов к загрузке в PyPI, чтобы он был широко доступен.

Обратите внимание: если вы хотите установить пакеты в редактируемом режиме (т. е. запустив pip install -e .), у вас должен быть действительный файл setup.py, кроме setup.cfg и pyproject.toml. Вы можете использовать тот же фиктивный установочный файл, которым я поделился в предыдущем разделе, который делает всего один вызов метода setup().

Так мне все еще нужен файл requirements.txt?

Короткий ответ: скорее всего вероятно, да. Предполагается, что файлы setuptools содержат абстрактные зависимости, а файлы requirements.txt должны содержать конкретные зависимости.

Для более полного ознакомления с назначением requirements.txt и setuptools вы можете прочитать одну из моих недавних статей, опубликованных ниже.



Последние мысли

В сегодняшней статье мы обсудили пакет setuptools и то, как использовать файлы setup.py и setup.cfg для управления зависимостями пакетов и упрощения распространения пакетов в Python.

Кроме того, мы обсудили различные параметры и метаданные, которые можно указать, а также различия между файлами setup.py и setup.cfg. Мы также обсудили файл requirements.txt и то, как его можно использовать для решения головоломки управления зависимостями в пакетах Python. Наконец, мы представили PEP517 и назначение файла с именем pyproject.toml.

И последнее замечание: помните, что рекомендации по распространению пакетов в Python постоянно развиваются, особенно в последние несколько лет, поэтому следите за обновлениями и время от времени следуйте рекомендациям.

Стать участником и читать все истории на Medium. Ваш членский взнос напрямую поддерживает меня и других писателей, которых вы читаете. Вы также получите полный доступ ко всем историям на Medium.



Подходящие статьи, которые могут вам понравиться