如何在不使用 setup.py 文件的情况下构建源代码分发?

How to build a source distribution without using setup.py file?

具有以下包结构

.
├── 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

但是根据maintainer of setuptools, a declarative build configuration is ideal and using an imperative build is going to be a code smell. So we replace setup.py with 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 文件的情况下构建源代码分发?

在 Python 包装方面没有任何东西 "obvious"。实际上,至少就目前而言,如果您正在使用 distutils/setuptools,则有必要创建一个(几乎)空的 setup.py 文件,即使您使用的是完全声明性的 setup.cfg

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

我也推荐chmod +x setup.py

在这种情况下,您只是自己将 "entry point" 写入构建系统,而 setup() 只是它的 main() 函数——但现在所有的参数都是传统上传递给 setup() 可以从 setup.cfg 读取。

现在如果你想制作一个源压缩包你仍然可以使用setup.py sdist:

./setup.py sdist

您还可以尝试通过 pyproject.toml 启用的替代构建系统之一,例如 Flit

这是一个有点争议的话题,目前的答案是,没有一种工具是每个人都同意的构建源代码分发的“正确方法”,也没有那个工具是什么。可以看到a long thread about it on the Python Packaging discourse.

我不愿以耐用格式提供太多包装建议,因为沙子总是在移动,但截至 2019 年 11 月,setup.py sdist 已弃用,但它 是否具有 PE​​P 517 和 PEP 518 旨在修复的所有缺点 - 即您必须自己创建构建环境(并了解所有构建依赖项),并且它 only 适用于 setuptools/distutils 及其等价物。

这不是“官方”建议,但目前(2020 年 12 月)setup.py sdistsetup.py bdist_wheel 的最佳替代品是使用 pypa-build。使用

安装一次
pip install build

并用作

python -m build --sdist --wheel

这会同时构建源代码分发和轮子。 这就是我构建 PEP 517 兼容包的方式。

这要求您的项目有 pyproject.toml,并且 pyproject.toml 必须有 build-system.requiresbuild-system.build-backend 键,但它适用于任何具有 PE​​P 的项目517 兼容后端(包括 flit)。

其他工具

为什么不使用 flitpoetryhatch?这些工具都可供那些想要使用它们的人使用,但它们并不是这个问题的答案。这个问题是关于使用声明性 setup.cfg 格式的 setuptools 构建的项目。 flitpoetry 都不是通用的 PEP 517 构建前端,因此它们 用作使用各自后端的项目的构建命令。

我对 hatch 不够熟悉,无法说明它是否可以使用后端 other 来管理项目而不是 setuptools,但是(同样,截至 2019 年 11 月) ,它 不是 一个 PEP 517 前端,如果你没有 setup.py 它就不会工作(它会引发错误“无法打开文件 setup.py",它会忽略你的 pyproject.toml 文件)。

如果您不想安装第 3 方工具并且不想创建临时文件 setup.py,您也可以使用

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