pyproject.toml和cython扩展模块

13
我有一个现有的Python项目,主要使用setup.py来构建项目。该项目有两个配置在setup.py中的Cython扩展模块。
最初我使用pip install -e .进行开发,但自从那时起我就使用python setup.py build_ext --inplace来仅在需要时重新构建扩展模块,这比安装包要快得多。
我开始将项目迁移到pyproject.toml,并在pyproject.toml中的[project]部分中包含项目配置。
我的setup.py基本上只包含了Cython扩展模块,我了解到这些模块目前无法迁移到'pyproject.toml'中。
现在我的问题是:python setup.py build_ext --inplace不再起作用,因为setup.py没有所有信息,并且没有查看pyproject.toml读取项目配置(因此缺少项目配置信息)。
我需要回退到原始的setup.py/*.cfg配置,还是有办法让setup.pypyproject.toml检索配置?

我不确定是否可以仅使用 pyproject.toml 来配置一个包,但我一直在与 setup.cfgsetup.py 一起使用它,并且能够使用 python3 setup.py build_ext -i 编译 Cython 扩展。您想让我添加一个带有示例的答案吗? - alfonsoSR
不用了,谢谢。我也是这么做的。 - Juergen
2个回答

13
以下是一个构建和使用 pyproject.toml 的小技巧示例:

pyproject.toml

[tool.setuptools]
py-modules = ["_custom_build"]

[tool.setuptools.cmdclass]
build_py = "_custom_build.build_py"

_custom_build.py

from setuptools import Extension
from setuptools.command.build_py import build_py as _build_py

class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return super().run()

    def initialize_options(self):
        super().initialize_options()
        if self.distribution.ext_modules == None:
            self.distribution.ext_modules = []

        self.distribution.ext_modules.append(
            Extension(
                "termial_random.random",
                sources=["termial_random/random.c"],
                extra_compile_args=["-std=c17", "-lm"],
            )
        )

这个工作很好,只是结果是没有平台规范的构建(例如,PACKAGE-VERSION-py3-none-any.whl),而不是预期的PACKAGE-VERSION-cp311-cp311-win_amd64.whl)。有什么想法吗? - undefined

1

对我来说,按照Cython文档setuptools文档中的建议进行操作是有效的。

requires列表中添加cython作为依赖项,这是我对pyproject.toml所做的唯一更改。

以下是setup.py的内容:

from setuptools import setup, Extension
from Cython.Build import cythonize
from Cython.Compiler import Options
import numpy

# These are optional
Options.docstrings = True
Options.annotate = False

# Modules to be compiled and include_dirs when necessary
extensions = [
    # Extension(
    #     "pyctmctree.inpyranoid_c",
    #     ["src/pyctmctree/inpyranoid_c.pyx"],
    # ),
    Extension(
        "pyctmctree.domortho",
        ["src/pyctmctree/domortho.pyx"], include_dirs=[numpy.get_include()],
    ),
]


# This is the function that is executed
setup(
    name='mypackage',  # Required

    # A list of compiler Directives is available at
    # https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives

    # external to be compiled
    ext_modules = cythonize(extensions, compiler_directives={"language_level": 3, "profile": False}),
)

注意:仅当您使用numpy的c版本时才需要get_include

一旦创建了setup.py文件,我可以使用
pip install -e . (在项目目录内)编译Cython扩展。

到目前为止,我已经注意到使用pip install -e .存在以下两个缺点:

  • 每次都会检查所需的软件包
  • 每一个.pyx文件都会被构建,而不考虑时间戳

以上情况会明显减缓开发速度。

更快捷的替代方法是:

  • python3 setup.py build_ext -i
  • python3 setup.py develop(虽然已弃用)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接