Как построить исходный дистрибутив без использования файла setup.py?


10

Со следующей структурой пакета

.
├── my_package
│   └── __init__.py
├── setup.cfg
└── setup.py

Содержание setup.py

from setuptools import setup
setup()

Содержание setup.cfg

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

Я могу построить колесо или источник распределения для my_packageэтого

pip wheel --no-deps -w dist .
# generates file ./dist/my_package-0.1-py3-none-any.whl
python setup.py sdist
# generates file ./dist/my_package-0.1.tar.gz

Но, по словам сопровождающего setuptools , декларативная конфигурация сборки идеальна, и использование императивной сборки будет пахнуть кодом. Поэтому мы заменим setup.pyна pyproject.toml:

.
├── my_package
│   └── __init__.py
├── setup.cfg
└── pyproject.toml

Содержание pyproject.toml

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

И вы все равно можете построить колесо так же, как и раньше, это работает. Но sdist не работает:

python: can't open file 'setup.py': [Errno 2] No such file or directory

Так как же вам на самом деле собрать файл .tar.gz с помощью setuptools ? Что такое инструмент для создания sdist? Я не хочу менять бэкэнд сборки. Похоже, что все другие инструменты упаковки пишут свои собственные точки входа в сборку, но я думал, что весь смысл определения декларативной системы сборки в метаданных заключается в том, чтобы вам не приходилось практиковаться в системе сборки, изучая, как каждый другой инструмент упаковки ожидает вызова или необходимости входить в интерпретатор и вызывать Python API вручную. Но PEP для требований к системе сборки уже более 2 лет. Я что-то упускаю здесь очевидное?

Как построить исходный дистрибутив без использования setup.pyфайла?

Ответы:


10

Это несколько спорная тема, и ответ на данный момент заключается в том, что нет единого инструмента, с которым все согласны, является «правильный путь» для создания исходных дистрибутивов, и каким бы он ни был. Вы можете увидеть длинную ветку об этом в дискурсе Python Packaging .

Я не решаюсь дать слишком много советов упаковки в прочных форматах , потому что песок всегда меняется, но по состоянию на ноябрь 2019 года, setup.py sdistявляется не рекомендуется, но это действительно имеет все недостатки , которые PEP 517 и PEP 518 были предназначены для исправления - а именно , что у вас есть создать среду сборки самостоятельно (и знать обо всех зависимостях сборки), и она работает только с setuptools / distutils и их эквивалентами.

Это не «официальная» рекомендация, но текущая лучшая замена для setup.py sdistи setup.py bdist_wheelиспользует версию командной строки pep517. Замена для sdist:

python -m pep517.build --source .

Вы можете одновременно создать колесо и исходный код:

python -m pep517.build --source --binary .

Вот как я собираю свои PEP 517-совместимые пакеты.

Это требует , чтобы ваш проекта есть pyproject.toml, и pyproject.tomlдолжна иметь build-system.requiresи build-system.build-backendключи, но он будет работать для любого проекта с PEP 517-совместимым бэкэндом ( в том числе flit).

Другие инструменты :

Почему бы не использовать flitили poetryили hatch? Все эти инструменты доступны для тех, кто хочет их использовать, но они не являются ответом на этот вопрос . Этот вопрос задают о проектах, построенных с setuptoolsиспользованием декларативного setup.cfgформата. Ни то, flitни другое не poetryдействуют как универсальные внешние интерфейсы сборки PEP 517, и поэтому они работают только как команды сборки для проектов, использующих свои соответствующие внутренние серверы.

Я не достаточно знаком с тем, hatchчтобы сказать, может ли он управлять проектами с бэкэндами, отличными от setuptools, но (опять же, по состоянию на ноябрь 2019 года), это не интерфейс PEP 517, и он не будет работать, если у вас нет а setup.py(это вызовет ошибку «не могу открыть файл setup.py» и проигнорирует ваш pyproject.tomlфайл).


Зачем сосредотачиваться на том, pep517.buildчто подразумевается только в качестве эксперимента, временной опоры, когда появляются такие продуктивные инструменты, как порхание, поэзия, люк и, возможно, даже больше?
— sinoroc

1
Потому что, по моим оценкам, это был успешный эксперимент (я и многие другие пользователи PyPA его используем), так как он имеет правильную семантику для работы, и потому что это единственный интерфейс общего назначения PEP 517, который я знаю. Флит и поэзия вертикально интегрированы в том, что они ожидают, что вы будете использовать их бэкэнд. Люк, кажется, делает много других вещей. pep517.buildэто простой инструмент, созданный именно для этой цели.
— Пол

Ах да, хорошая мысль. Я сосредоточился на бэк-эндах сборки. И я действительно думал, что pep517.buildбыл одним из них. Но не совсем, это на самом деле сборка. Также люк не готов PEP517, как я вижу сейчас.
— sinoroc

1
Я обновил свой ответ, чтобы ответить на ваш вопрос.
— Пол

Да, идеально. Я удаляю свой ответ.
— sinoroc

-1

Там нет ничего "очевидного", когда дело доходит до упаковки Python. Действительно, на данный момент, по крайней мере, если вы используете distutils / setuptools, необходимо создать (почти) пустой setup.pyфайл, даже если вы используете полностью декларативный setup.cfg:

#!/usr/bin/env python
from setuptools import setup
setup()

Я также рекомендую chmod +x setup.py.

В этом случае вы просто пишете «точку входа» в систему сборки самостоятельно, и setup()это просто main()функция для нее - но теперь вместо этого setup()можно прочитать все аргументы, которые традиционно передавались setup.cfg.

Теперь вы все еще можете использовать, setup.py sdistесли хотите сделать архив с исходным кодом:

./setup.py sdist

Вы также можете попробовать одну из альтернативных систем сборки, которые включены через pyproject.toml, например, Flit .


Не уверен, почему за это проголосовали; это в основном правильно, даже если есть другие решения.
— Iguananaut

2
Заголовок вопроса: «Как создать исходный дистрибутив без использования файла setup.py?» Этот ответ, кажется, просто демонстрирует «вот как воссоздать тот же файл setup.py, который вы только что удалили», что бесполезно.
— утконос

Да, но это было основано на неправильном понимании того, что написание декларативного setup.cfgозначает, что setup.pyбольше нет необходимости использовать setuptools, что не соответствует действительности. То, что название вопроса вводит в заблуждение, не означает, что ответ таков. Они написали в основной части вопроса «Так как же вам на самом деле собрать файл .tar.gz с помощью setuptools ?» который отвечает правильно.
— Iguananaut

1
Это на самом деле правда. setuptools не требует файла setup.py, если вы используете PEP 517.
— Paul

«если вы используете PEP 517», за исключением большинства людей. Он все еще предварительный и почти не упоминается в package.python.org . Это не то, что у вас будет, если вы не знаете, искать это. Если вы просто хотите, чтобы setuptools работал как обычно, это правильно.
— Iguananaut
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.