如何在不使用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.pypyproject.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文件的情况下构建源代码分发?

Answers:


10

这是一个有争议的话题,目前的答案是,没有一个人人都认同的工具是构建源代码发行版的“正确方法”,也没有该工具会是什么。您可以在Python Packaging文章中看到关于它的长篇文章

我犹豫耐用格式给你太多的包装建议,因为沙总是转移,但截至11月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.tomlpyproject.toml必须具有build-system.requiresbuild-system.build-backend键,但是它适用于任何与PEP 517兼容的后端(包括flit)的项目。

其他工具

为什么不使用flitor poetryhatch?这些工具都可供想要使用它们的人使用,但它们不能解决这个问题。这个问题问的setuptools是使用声明性setup.cfg格式构建的项目。PEP 517 既不构建前端flit也不poetry充当其通用前端,因此它们仅用作使用其各自后端的项目的构建命令。

我不熟悉不够用hatch说它是否能与后端管理项目比setuptools的,但(再次,为2019年11月),它是不是一个PEP 517前端,也不会工作,如果你没有a setup.py(它将引发错误“无法打开文件setup.py”,并且将忽略您的pyproject.toml文件)。


为什么pep517.build在有诸如flit,诗歌,孵化之类的生产工具,甚至可能还有更多工具的情况下,只关注实验只是一个临时的拐杖?
sinoroc

1
在我看来,这是一次成功的实验(我和许多其他PyPA人士都在使用它),因为它具有正确的工作语义,并且因为它是我所知道的唯一通用的PEP 517构建前端。flit和诗歌是垂直整合的,因为它们希望您使用其后端。孵化似乎会做很多其他事情。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,这是不正确的。仅仅因为问题的标题具有误导性,并不意味着答案就是。他们在问题的正文中写道:“那么,您实际上应该如何使用setuptools构建.tar.gz文件?” 这可以正确回答。
Iguananaut

1
这是真的。如果你正在使用PEP 517的setuptools不需要setup.py文件
保罗

“如果您使用的是PEP 517”,除了大多数人以外。它仍然是临时的,甚至在Packaging.python.org中甚至都没有提到。除非您知道要寻找它,否则您不会拥有它。如果您只是想让setuptools像以前那样工作,那是正确的。
Iguananaut
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.