gpt4 book ai didi

python - 如何在 Cython 中测试 cdef 函数?

转载 作者:太空狗 更新时间:2023-10-29 18:05:15 25 4
gpt4 key购买 nike

我有一个 .pyx 文件,我在其中定义了一些函数,例如

cdef double foo(double a) nogil:
return 3. * a

我如何在 pyx 文件之外对此类函数的行为进行单元测试?由于它们是 cdef,我无法简单地导入它们...

最佳答案

要测试 cdef 功能,您需要在 Cython 中编写测试。可以尝试使用 cpdef 函数,但并非所有签名都可以在这种情况下使用(例如使用指针的签名,如 int *float *等等)。

要访问 cdef 函数,您需要通过 pxd 文件“导出”它们(对于 cdef-functions of extension types 也可以这样做):

#my_module.pyx:
cdef double foo(double a) nogil:
return 3. * a

#my_module.pxd:
cdef double foo(double a) nogil

现在可以在 Cython 测试器中导入和测试功能:

#test_my_module.pyx
cimport my_module

def test_foo():
assert my_module.foo(2.0)==6.0
print("test ok")

test_foo()

现在

>>> cythonize -i my_module.pyx
>>> cythonize -i test_my_module.pyx
>>> python -c "import test_my_module"
test ok

从那里去哪里取决于您的测试基础设施。


例如,如果您使用 unittest-module,那么您可以使用 pyximport 来 cythonize/load test-module 检查它并将所有测试用例转换为 unittest-test例或直接在您的 cython 代码中使用 unittest(可能是更好的解决方案)。

这是 unittest 的概念证明:

#test_my_module.pyx
cimport my_module
import unittest

class CyTester(unittest.TestCase):
def test_foo(self):
self.assertEqual(my_module.foo(2.0),6.0)

现在我们只需要在纯 python 中翻译和导入它就可以对其进行unittest:

#test_cy.py 
import pyximport;
pyximport.install(setup_args = {"script_args" : ["--force"]},
language_level=3)

# now drag CyTester into the global namespace,
# so tests can be discovered by unittest
from test_my_module import *

现在:

>>> python -m unittest test_cy.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

顺便说一句,不需要显式地对 pyx 模块进行 cythonize - pyximport 会自动为我们完成。

警告:pyximport 将 cythonized c 文件缓存在 ~/.pyxbld(或其他操作系统上的类似文件)中,只要因为 test_my_module.pyx 没有改变,扩展不会重建,即使它的依赖关系发生了变化。这可能是一个问题(除其他外),当 my_module 更改并导致二进制不兼容时(幸运的是,如果是这种情况,python 会发出警告)。

通过传递 setup_args = {"script_args": ["--force"]} 我们强制重建。

另一种选择是删除缓存文件(可以使用临时目录,例如使用 tempfile.TemporaryDirectory() 创建,通过 pyximport.install(build_dir=...) ),这具有保持系统清洁的优点。

需要明确的 language_level ( what is language_level? ) 以防止警告。


如果您使用虚拟环境并通过 setup.py(或类似的工作流程)安装 cython-package,您需要 to make sure that *.pxd files are also included into installation ,即您的安装文件需要增加:

from setuptools import setup, find_packages, Extension
# usual stuff for cython-modules here
...

kwargs = {
# usual stuff for cython-modules here
...

#ensure pxd-files:
'package_data' : { 'my_module': ['*.pxd']},
'include_package_data' : True,
'zip_safe' : False #needed because setuptools are used
}

setup(**kwargs)

关于python - 如何在 Cython 中测试 cdef 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42259741/

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