如何构建符合 PEP 517 的 C 扩展,即使用 pyproject.toml 而不是 setup.py?

Dr *_*Leo 26 python setuptools setup.py python-packaging pyproject.toml

我想为 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)
Run Code Online (Sandbox Code Playgroud)

现在,挑战是将以上内容放入 a pyproject.tomlplus a中setup.cfg

文档setuptools建议pyproject.toml如下:

[build-system]
requires = [
    "setuptools >=52.0",
        'wheel >= 0.36']
build-backend = "setuptools.build_meta"
Run Code Online (Sandbox Code Playgroud)

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

Evg*_*423 15

pyproject.toml严格来说并不意味着要替换setup.py,而是为了确保它的正确执行(如果仍然需要的话)(请参阅PEP\xc2\xa0517我的答案):

\n
\n

如果build-backend密钥存在,则优先,并且源树遵循指定后端的格式和约定(因此除非后端需要,否则不需要setup.py)。项目可能仍然希望包含一个以便与不使用此规范的工具兼容。setup.py

\n
\n

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

\n
\n

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

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

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

\n
\n

事实上,如果虚数不存在,setuptools 仍然会使用它setup.py

\n

注意: 由于 version\xc2\xa061.0.0 setuptools允许在file中指定项目元数据和其他配置选项pyproject.toml。它的使用看起来更有吸引力,因为该文件具有另一个更有用的功能,并且允许以标准化的、与工具无关的方式指定大多数元数据。

\n
\n

话虽这么说,如果您想尽可能坚持静态方式,您可以将所有可以移动到文件中的内容暂时pyproject.toml保留在其中:setup.py

\n pyproject.toml\n
[build-system]\nrequires = ["setuptools>=61"]\nbuild-backend = "setuptools.build_meta"\n\n[project]\nname = "mypackage"\n# more metadata\n
Run Code Online (Sandbox Code Playgroud)\n setup.py\n
from setuptools import setup, Extension\n\nsetup_args = dict(\n    ext_modules = [\n        Extension(\n            \'mypackage.mymodule\',\n            [\'lib/mymodule.c\', \'lib/mypackage.c\', \'lib/myalloc.c\'],\n            include_dirs = [\'lib\'],\n            py_limited_api = True\n        )\n    ]\n)\nsetup(**setup_args)\n
Run Code Online (Sandbox Code Playgroud)\n

  • @not2qubit 是的,确实如此。[setuptools 文档建议相同](https://setuptools.pypa.io/en/latest/userguide/ext_modules.html)。 (3认同)