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

Posted

技术标签:

【中文标题】如何在不使用 setup.py 文件的情况下构建源代码分发?【英文标题】:How to build a source distribution without using setup.py file? 【发布时间】:2020-03-04 08:14:15 【问题描述】:

采用如下封装结构

.
├── 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 的说法,声明式构建配置是理想的,使用命令式构建将是一种代码味道。所以我们用pyproject.toml替换setup.py

.
├── 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 文件的情况下构建源代码分发?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

我不愿提供太多耐用格式的包装建议,因为情况总是在变化,但截至 2019 年 11 月,setup.py sdist没有被弃用,但它确实 > 具有 PE​​P 517 和 PEP 518 旨在解决的所有缺点 - 即您必须自己创建构建环境(并了解所有构建依赖项),并且它适用于 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 键,但它适用于具有PEP 517 兼容后端(包括flit)的任何项目.

其他工具

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

我对@9​​87654340@ 不够熟悉,无法说明它是否可以管理具有 其他 后端而不是 setuptools 的项目,但是(同样,截至 2019 年 11 月),不能 一个 PEP 517 前端,如果您没有 setup.py,它将无法工作(它会引发错误“无法打开文件 setup.py”,它会忽略您的 pyproject.toml 文件)。

【讨论】:

为什么要关注pep517.build,这只是一个实验,当有 flit、诗歌、hatch 等生产工具时的临时拐杖,甚至可能更多? 因为在我看来这是一个成功的实验(我和许多其他 PyPA 人都在使用它),因为它具有适合这项工作的正确语义,并且因为它是唯一的通用 PEP 517 构建我知道的前端。 flit 和诗歌是垂直集成的,因为它们希望您使用它们的后端。孵化似乎做了很多其他的事情。 pep517.build 正是为此目的而构建的简单工具。 啊,对,好点。我专注于构建后端。我实际上认为pep517.build 就是其中之一。但根本不是,它实际上是一个构建前端。我现在看到的 hatch 还没有准备好 PEP517。 是的,完美。我删除了我的答案。 没有 setup.py 会影响可编辑安装吗? pip install -e folder【参考方案3】:

在 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。

【讨论】:

不确定为什么会被否决;就算有其他解决办法也基本正确。 问题标题是“如何不使用使用setup.py文件构建源代码分发?”这个答案似乎只是演示“这是如何重新创建刚刚删除的相同 setup.py 文件”,这没有用。 是的,但这是基于一种误解,即编写声明性 setup.cfg 意味着不再需要使用 setuptools 来使用 setup.py,这是不正确的。仅仅因为问题的标题具有误导性并不意味着答案是。他们在问题的正文中写道“那么您应该如何使用 setuptools 实际构建 .tar.gz 文件?”这回答正确。 确实是这样。如果您使用的是 PEP 517,setuptools 不需要 setup.py 文件。 "如果你使用的是 PEP 517" 除了大多数人不是。它仍然是临时的,甚至在 packaging.python.org 中几乎没有提及。除非你知道去寻找它,否则你不会拥有它。如果您只想让 setuptools 像往常一样正常工作,这是正确的。

以上是关于如何在不使用 setup.py 文件的情况下构建源代码分发?的主要内容,如果未能解决你的问题,请参考以下文章

在 CMake 中使用 setup.py 构建 python 包

没有 sudo 的 python setup.py 安装

python的构建工具——setup.py文件

如何在不下载整个片段的情况下使用媒体源缓冲区和分段 mp4 在特定时间启动视频?

如何使用和制作 Python 安装模块

在 C++ 中嵌入 Cython