如何处理Cython中的ValueError
我对Cython的扩展类型还比较陌生,最近在运行时遇到了一个和Cython有关的ValueError,搞得我很困惑:
ValueError: vrptwms.node.Node has the wrong size, try recompiling
Node类是在vrptwms目录下的node.pxd和node.pyx文件中定义的。前者的内容是
cdef class Node:
"""
docstring
"""
cdef public float x, y, demand
cdef public float earliest_start, latest_start, servicetime
cdef public int id
后者的内容是(我暂时去掉了所有的类型声明,希望能找到问题所在)
cdef class Node:
"""
Represents either a customer or the depot.
"""
# pylint: disable-msg=C0103, R0913
def __init__(self,
id_,
x,
y,
demand,
earliest_start,
latest_start,
servicetime):
"""
docstring
"""
self.x = float(x)
self.y = float(y)
self.demand = float(demand)
self.earliest_start = float(earliest_start)
self.latest_start = float(latest_start)
self.servicetime = float(servicetime)
self.id = int(id_)
# some internal functions
然后,node类是通过另一个文件problemreader.pyx包含进来的,方法如下:
from vrptwms.node cimport Node
from vrptwms.node import Node
编译没有任何问题。setup.py文件包含了
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("route", ["fastroute.pyx"]),
Extension("node", ["node.pyx", "node.pxd"]),
Extension("problemreader", ["problemreader.pyx"]),
]
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
)
我还尝试把node.pxd添加到problemreader扩展中,但没有成功。问题出现在以下生成的C代码中
__pyx_ptype_7vrptwms_4node_Node = __Pyx_ImportType("vrptwms.node", "Node", sizeof(struct __pyx_obj_7vrptwms_4node_Node), 1); if (unlikely(!__pyx_ptype_7vrptwms_4node_Node)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
并导致了
Traceback (most recent call last):
File "./cli.py", line 16, in <module>
from vrptwms.problemreader import ProblemReader
File "node.pxd", line 9, in init problemreader (problemreader.c:4991)
cdef class Node:
ValueError: vrptwms.node.Node has the wrong size, try recompiling
我多次删除了所有生成的.c、.so和.o文件,但问题依然存在。任何提示(包括我可能错过的文档链接)都非常感谢。
编辑:如果我使用旧式的相对导入(比如用import node而不是vrptwms.node)并且去掉init.py文件,问题就不会出现——所以源代码本身没有问题。我创建了一个小测试用例来重现这个问题:c_test.tar.gz(需要解压到PYTHONPATH目录下),还有一个几乎相同的案例,没有使用包,问题没有重现:c_test_w.tar.gz。
2 个回答
0
我不太明白你在这里做什么:
from vrptwms.node cimport Node
from vrptwms.node import Node
当你两次导入同一个名字时,第二次导入会覆盖第一次的内容。
2
罗伯特·布拉德肖在cython-users邮件列表上提出了一些建议。简单来说,就是手动用cython *.pyx
命令重新编译.pyx文件,然后运行原来的设置脚本,这样就能正常工作。此外,还有一种更新的写设置脚本的方法,详细信息可以在CEP 201 - Distutils Preprocessing中找到,这种方法应该能帮忙,但在我现在使用的Cython 0.14.1版本中并不奏效。