24

具有以下封装结构

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

那么您应该如何使用 setuptools实际构建 .tar.gz 文件?创建 sdist 的面向用户的工具是什么?我不想更改构建后端。看起来其他打包工具都编写了自己的构建入口点,但我认为在元数据中定义声明式构建系统的全部目的是让您不必亲自动手构建系统,学习每个需要调用不同的打包工具,或者必须进入解释器并手动调用 Python API。但是构建系统要求的 PEP 现在已经超过 2 年了。我在这里遗漏了一些明显的东西吗?

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

4

3 回答 3

24

这是一个有争议的话题,目前的答案是,没有一个工具是每个人都同意的构建源代码分发的“正确方法”,也没有那个工具会是什么。你可以在 Python Packaging discourse 上看到一个关于它的长线程

我不愿提供太多耐用格式的包装建议,因为沙子总是在变化,但截至 2019 年 11 月,setup.py sdist它并没有被弃用,但它确实具有 PE​​P 517 和 PEP 518 旨在解决的所有缺点 - 即你有自己创建构建环境(并了解所有构建依赖项),它适用于 setuptools/distutils 及其等价物。

这不是“官方”建议,而是当前(2020 年 12 月)的最佳替代品,setup.py sdist并且setup.py bdist_wheel正在使用pypa-build。安装一次

pip install build

并用作

python -m build --sdist --wheel

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

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

其他工具

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

我不太熟悉hatch它是否可以使用 setuptools 以外的后端管理项目但是(同样,截至 2019 年 11 月),它不是PEP 517 前端,如果你没有它,它将无法工作a setup.py(它会引发错误“无法打开文件 setup.py”,并且会忽略您的pyproject.toml文件)。

于 2019-11-07T20:31:24.103 回答
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如果您想制作源 tarball,您仍然可以使用:

./setup.py sdist

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

于 2019-11-07T17:40:14.243 回答
1

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

python -c "import setuptools; setuptools.setup()" sdist
于 2021-08-23T12:03:42.753 回答