如何现代化基于 setup.py 的项目?

是否应添加 pyproject.toml

强烈建议使用 pyproject.toml 文件。 pyproject.toml 文件的存在本身并没有带来太多。[1] 实际强烈建议的是 pyproject.toml 中的 [build-system] 表。

是否应删除 setup.py

不,在现代基于 Setuptools 的项目中,setup.py 可以存在。setup.py 文件是 setuptools 的有效配置文件,它恰好是用 Python 编写的。然而,以下命令已被弃用,并且**不得**再运行,应使用其推荐的替代命令:

已弃用

建议

python setup.py install

python -m pip install .

python setup.py develop

python -m pip install --editable .

python setup.py sdist

python -m build

python setup.py bdist_wheel

了解更多详情

从何开始?

项目 必须在其源代码树的根目录下包含一个 pyproject.toml 文件,其中包含一个 [build-system] 表,如下所示:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

这是让 构建前端 知道 Setuptools 是该项目的 构建后端 的标准化方法。

请注意,pyproject.toml 文件的存在(即使是空的)也会触发 pip 更改其默认行为以使用*构建隔离*。

了解更多详情

如何处理额外的构建时依赖项?

除了 setuptools 本身之外,如果 setup.py 依赖于其他第三方库(Python 标准库之外),则必须将它们列在 [build-system] 表的 requires 列表中,以便构建前端知道在构建 分发包 时安装它们。

例如,像这样的 setup.py 文件

import setuptools
import some_build_toolkit  # comes from the `some-build-toolkit` library

def get_version():
    version = some_build_toolkit.compute_version()
    return version

setuptools.setup(
    name="my-project",
    version=get_version(),
)

需要一个像这样的 pyproject.toml 文件(setup.py 保持不变)

[build-system]
requires = [
    "setuptools",
    "some-build-toolkit",
]
build-backend = "setuptools.build_meta"

了解更多详情

什么是构建隔离功能?

构建前端通常会创建一个临时的虚拟环境,在其中仅安装 build-system.requires 下列出的构建依赖项(及其依赖项),并在此环境中触发构建。

对于某些项目,这种隔离是不需要的,可以通过以下方式禁用:

  • python -m build --no-isolation

  • python -m pip install --no-build-isolation

了解更多详情

如何处理打包元数据?

所有静态元数据都可以选择移动到 pyproject.toml 中的 [project] 表中。

例如,像这样的 setup.py 文件

import setuptools

setuptools.setup(
    name="my-project",
    version="1.2.3",
)

可以完全替换为像这样的 pyproject.toml 文件

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "my-project"
version = "1.2.3"

阅读 声明项目元数据:[project] 表 以获取 [project] 表中允许的内容的完整规范。

如何处理动态元数据?

如果某些打包元数据字段不是静态的,则需要在此 [project] 表中将它们列为 dynamic

例如,像这样的 setup.py 文件

import setuptools
import some_build_toolkit

def get_version():
    version = some_build_toolkit.compute_version()
    return version

setuptools.setup(
    name="my-project",
    version=get_version(),
)

可以按如下方式进行现代化

[build-system]
requires = [
    "setuptools",
    "some-build-toolkit",
]
build-backend = "setuptools.build_meta"

[project]
name = "my-project"
dynamic = ["version"]
import setuptools
import some_build_toolkit

def get_version():
    version = some_build_toolkit.compute_version()
    return version

setuptools.setup(
    version=get_version(),
)

了解更多详情

如果某些无法更改的东西期望一个 setup.py 文件怎么办?

例如,存在一个无法轻易更改的进程,它需要执行诸如 python setup.py --name 之类的命令。

即使其所有内容都已移至 pyproject.toml,项目源代码树中保留一个 setup.py 文件也完全没有问题。该文件可以像这样最小化:

import setuptools

setuptools.setup()

在哪里可以阅读更多信息?