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

Мы обновляем портфель BeeWare 0.3.1 для упаковки, в которой используетсяpyproject.toml вместо того setup.py чтобы указать, как упаковать, включая зависимости, которые нужно включить в пакет.

Вот минимальный пример pyproject.tomlдля портфеля:

[tool.briefcase.app.exampleapp]
formal_name = "exampleapp"
description = "something"
requires = ['PyQt5', 'qtconsole']
sources = ['exampleapp']

Мы хотели бы получить доступ к списку требований от setup.py, поэтому нам не придется копировать его в оба файла и синхронизировать их. Мы не готовы отказаться от setuptools, это только для упаковки. Альтернативой является, конечно, позволитьsetup.py автоматически генерировать pyproject.tomlфайл, но это кажется немного назад по сравнению с намерением PEP 518.

1 ответ

Решение

Насколько я могу судить, портфель на самом деле не совместим с PEP 517 (по крайней мере, не по умолчанию). Он используетpyproject.toml файл, но не заполняет [build-system]раздел, поэтому в этом файле должна быть возможность установить фактический сервер сборки PEP 517, не вызывая конфликта.

pyproject.toml

[build-system]
build-backend = 'setuptools.build_meta'
requires = [
    'setuptools',
    'toml',
]

[tool.briefcase.app.exampleapp]
formal_name = 'exampleapp'
description = 'something'
requires = ['PyQt5', 'qtconsole']
sources = ['exampleapp']

setup.py

#!/usr/bin/env python3

import pathlib

import pkg_resources
import setuptools
import toml

def _parse_briefcase_toml(pyproject_path, app_name):
    pyproject_text = pyproject_path.read_text()
    pyproject_data = toml.loads(pyproject_text)
    briefcase_data = pyproject_data['tool']['briefcase']
    app_data = briefcase_data['app'][app_name]
    setup_data = {
        'name': pkg_resources.safe_name(app_data['formal_name']),
        'version': briefcase_data['version'],
        'install_requires': app_data['requires'],
        # ...
    }
    return setup_data

def _setup():
    app_name = 'exampleapp'
    pyproject_path = pathlib.Path('pyproject.toml')
    setup_data = _parse_briefcase_toml(pyproject_path, app_name)
    setuptools.setup(**setup_data)

if __name__ == '__main__':
    _setup()

Затем pip и другие интерфейсы, совместимые с PEP 517, должны иметь возможность создавать и устанавливать проект, делегируя команды setuptools, при этом заботясь о правильной настройке среды сборки, содержащей как setuptools, так и toml.

Я думаю, можно было бы также позволить портфелю обрабатывать синтаксический анализpyproject.toml файл (возможно, с briefcase.config.parse_config(...)), но это не задокументировано, поэтому я не знаю, насколько стабильны эти API.

Другие вопросы по тегам