Как собрать исходный код без использования файла 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.