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

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

.
├── 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 файл?

3 ответа

Решение

Это несколько спорная тема, и ответ на данный момент заключается в том, что не существует единого инструмента, который, по общему мнению, был бы "правильным" для создания исходных дистрибутивов, и каким бы он был. Вы можете увидеть длинную ветку об этом в обсуждении 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 файл).

Если вы не хотите устанавливать сторонний инструмент и не хотите создавать временный setup.py, вы также можете использовать

      python -c "import setuptools; setuptools.setup()" sdist

Когда дело доходит до упаковки 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.

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