gpt4 book ai didi

python - 诗歌 + Cython + 测试(Nosetests)

转载 作者:行者123 更新时间:2023-12-05 05:05:28 26 4
gpt4 key购买 nike

我使用 Poetry 构建带有 cython 扩展的包。现在我想为它编写测试(最好使用 nosetest)。问题是我需要预编译二进制文件,通常使用 setup.py build_clib build_ext --inplace

对我来说最好的解决方案是运行测试而不在目录中创建额外的 .py.sh 文件,因为我已经有了 build.py。在虚拟环境中安装包后运行测试就可以了,就像在readthedocs服务器上实现的一样。

我也熟悉了 taskipy,所以我的 pyproject.toml 中的一些 bash 命令也可以。欢迎与 pyproject.toml 一起使用的任何其他包。

也许 Poetry 有任何钩子(Hook),因为它在创建 .whl 分发文件时进行了 cythonizes 和 comiles。

我们将不胜感激。

UPD Tox 看起来是合适的工具,但它在目录中时看不到 pyproject.toml。非常欢迎在包或教程中使用 tox 和 cython 的 repos 链接。

最佳答案

如果扩展是分发的一部分,除了运行 poetry install 之外你不需要做任何事情 - poetry 将就地构建扩展作为项目的可编辑安装。

在其他情况下,您可以在测试中嵌入调用 distutils 命令作为套件设置/拆卸的一部分。我对 nose 不是很熟悉,但这里有一个简单的例子。假设我有一个 fib.pyx(这是 Cython 书中的一个例子):

def fib(long n):
'''Returns the nth Fibonacci number.'''
cdef long a=0, b=1, i
for i in range(n):
a, b = a + b, a
return a

一个 test_fib.py 模块,用于构建 fib 库并在测试成功时将其删除:

from distutils.dist import Distribution
from distutils.core import Extension
from pathlib import Path
from Cython.Build import cythonize


fib_source = Path('fib.pyx')

# distutils magic. This is essentially the same as calling
# python setup.py build_ext --inplace
dist = Distribution(attrs={'ext_modules': cythonize(fib_source.name)})
build_ext_cmd = dist.get_command_obj('build_ext')
build_ext_cmd.ensure_finalized()
build_ext_cmd.inplace = 1
build_ext_cmd.run()

fib_obj = Path(build_ext_cmd.get_ext_fullpath(fib_source.stem))

# the lib was built, so the import will succeed now
from fib import fib


def teardown_module():
# remove built library
fib_obj.unlink()

# if you also want to clean the build dir:
from distutils.dir_util import remove_tree
remove_tree(build_ext_cmd.build_lib)
remove_tree(build_ext_cmd.build_temp)


# sample tests

def test_zero():
assert fib(0) == 0


def test_ten():
assert fib(10) == 55

您可能正在自定义 build.py 中自定义 setup_kwargs。要重用此代码,请调整 dist 初始化,例如:

from build import build

setup_kwargs = {}
build(setup_kwargs)
dist = Distribution(attrs=setup_kwargs)
...

pytest 例子

使用 pytest 可以更方便地组织事物。创建一个名为 conftest.py 的文件,其中包含提取到 Hook 的设置/拆卸代码:

# conftest.py

from distutils.core import Extension
from distutils.dist import Distribution
from distutils.dir_util import remove_tree
from pathlib import Path
from Cython.Build import cythonize


def pytest_sessionstart(session):
fib_source = Path('fib.pyx')
dist = Distribution(attrs={'ext_modules': cythonize(fib_source.name)})
build_ext_cmd = dist.get_command_obj('build_ext')
build_ext_cmd.ensure_finalized()
build_ext_cmd.inplace = 1
build_ext_cmd.run()
session.fib_obj = Path(build_ext_cmd.get_ext_fullpath(fib_source.stem))


def pytest_sessionfinish(session):
session.fib_obj.unlink()

现在测试变得更加清晰,设置代码在整个测试 session 中运行一次。上面的测试示例,重新访问:

from fib import fib


def test_zero():
assert fib(0) == 0


def test_ten():
assert fib(10) == 55

关于python - 诗歌 + Cython + 测试(Nosetests),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60501869/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com