【发布时间】:2021-02-05 07:24:38
【问题描述】:
我有两个 .pyx 文件 - bar.pyx 和 baz.pyx。我想将它们组合成一个 .so 文件。
在baz.pyx 中,我有一个函数baz,它应该进行一些检查并在出现问题时引发异常。在bar.pyx 我想调用baz() 并期望在打印回溯的情况下引发异常。
不幸的是,无论我尝试什么,都会遇到一些其他运行时错误。
setup.py 中的扩展
[
Extension(
'testlib.baz', ['src/testlib/baz.pyx'],
),
Extension(
'testlib.foo', ['src/testlib/bar.pyx', 'src/testlib/baz.c'],
),
]
如何测试
import testlib.foo
testlib.foo.foo_baz()
变体 1
# baz.pyx
cdef public baz():
raise ValueError
# bar.pyx
cdef extern baz()
def foo_baz():
baz() # Segmentation fault
变体 2
# baz.pyx
cdef public int baz() except -1:
PyErr_SetNone(ValueError)
return -1
# bar.pyx
cdef extern int baz() except -1
def foo_baz():
baz() # SystemError: <built-in function foo_baz> returned NULL without setting an error
我可以从baz 返回一些值,并根据返回值在foo_baz 中引发异常,但我希望bar.pyx 中存在最低逻辑。
# baz.pyx
cdef public int baz():
return -1
# bar.pyx
cdef extern int baz()
def foo_baz():
if baz() == -1:
raise ValueError # OK
【问题讨论】:
-
这是因为您从不导入
baz模块。 Cython 在模块导入期间为异常设置全局变量。由于这个全局变量从未被初始化,所以一切都出错了。解决方案可能不是尝试将多个模块强制放入单个 .so 文件:它不是为它设计的,而且要正确执行非常复杂。 -
似乎合法,然后用 C 重写 baz.pyx。谢谢!
标签: python exception cython cythonize