7

我想为 CPython 构建一个 C 扩展。我可以用传统的setup.py文件来做。但是,由于 PEP 517 中提到的原因,我更喜欢使用pyproject.toml. 我知道这setuptools是唯一可以在所有相关平台上构建 C 扩展的构建后端。事实上,我不知道有任何后端能够与过时的distutils.

在这种背景下,一个常见的setup.py看起来像这样:

from setuptools import setup, Extension
kwargs = dict(
    name='mypackage',
    # more metadata
    ext_modules=[
        Extension('mypackage.mymodule', ['lib/mymodule.c',
                                         'lib/mypackage.c',
                                         'lib/myalloc.c'],
                  include_dirs=['lib'],
                  py_limited_api=True)])

setup(**kwargs)

现在,挑战是将上述内容放入一个pyproject.tomlplus asetup.cfg中。

setuptools文档建议这样pyproject.toml

[build-system]
requires = [
    "setuptools >=52.0",
        'wheel >= 0.36']
build-backend = "setuptools.build_meta"

此外,实际的元数据应该进入setup.cfg. 但是,我还没有找到任何关于如何将ext_moduleskwarg(尤其是Extension()调用)翻译成setup.cfg语法的解释。

4

1 回答 1

3

pyproject.toml并不是严格意义上的替换setup.py,而是确保它在仍然需要时正确执行(参见PEP 517我的答案):

如果build-backend存在密钥,则优先,源代码树遵循指定后端的格式和约定(因此 nosetup.py是必需的,除非后端需要它)。项目可能仍希望包含setup.py与不使用此规范的工具的兼容性。

虽然setuptools尝试将所有内容从脚本移动到配置文件中,但这并不总是可能的

元数据有两种类型:静态和动态。

  • 静态元数据(setup.cfg):保证每次都相同。这更简单,更易于阅读,并且避免了许多常见错误,例如编码错误。
  • 动态元数据 ( setup.py):可能是不确定的。任何在安装时动态或确定的项目,以及扩展模块或扩展setuptools,都需要进入setup.py.

静态元数据应该是首选,而动态元数据应该仅在绝对必要时用作逃生舱口。

事实上,setup.cfg-only 项目现在只有 2 年的时间,并且如果它不存在,setuptools 将使用一个虚构setup.py的。


话虽如此,如果您想尽可能地坚持静态方式,您可以将所有可能的内容移到setup.cfg文件中,并将其余部分保留在setup.py

setup.cfg
[metadata]
name = mypackage
; more metadata
setup.py
from setuptools import setup, Extension

setup_args = dict(
    ext_modules = [
        Extension(
            'mypackage.mymodule',
            ['lib/mymodule.c', 'lib/mypackage.c', 'lib/myalloc.c'],
            include_dirs = ['lib'],
            py_limited_api = True
        )
    ]
)
setup(**setup_args)

但我会把所有的东西都放进去setup.py

于 2021-03-04T16:37:34.733 回答