【问题标题】:What is the reason for this Cython compile error when declaring a cpdef enum?声明 cpdef 枚举时出现此 Cython 编译错误的原因是什么?
【发布时间】:2016-06-27 09:04:19
【问题描述】:

我正在使用 Python 3.4.2 和 Cython 0.24 和 GCC 4.9.1 开发 Raspberry PI。
我想使用 cpdef enum 创建 PEP 435 样式的 Python 枚举(自 Python 3.4 起可用)。此功能在Cython 0.21 中引入。

我正在使用以下源代码:

#lib.h file
typedef enum { A, B, C, D } test;

#lib.pyx file
cdef extern from "lib.h":
    cpdef enum test:
        A, B, C, D

def t1():
    for t in test: print(t.value)

但是,几个编译错误说几次或多或少相同:
- lib.c:4664:20: error: invalid application of 'sizeof' to incomplete type 'enum test'
- lib.c:2599:45: error: type of formal parameter 1 is incomplete __pyx_t_4 = __Pyx_PyInt_From_enum__test(C); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 56, __pyx_L1_error)

在我运行的交互式 shell 中:

>>> from enum import Enum
>>> Enum
<enum 'Enum'>

显然,该模块似乎存在并且正在工作。

我的问题是:这些错误的原因可能是什么?

【问题讨论】:

    标签: python python-3.x enums compiler-errors cython


    【解决方案1】:

    可以使用ctypedefcdef. 声明枚举
    尝试像这样定义你的枚举:

    cdef enum Test:
        A, B, C, D
    

    ctypedef enum Test:
        A, B, C, D
    

    【讨论】:

    • cpdef enum Test正如我在介绍中提到的。 “现在可以将枚举声明为 cpdef 以将其值导出到模块的 Python 命名空间。” Cython Changelog。也许你重读了我的问题......
    • 如果是我,我会尝试尝试/旧的方法,以确保问题出在我认为的位置,当我确定根本原因是什么时,我会解决问题的。但这只是我。
    • 老方法没问题。
    【解决方案2】:

    我认为您的标题中的分号位置可能有误?同样在标题中定义test,但在cython 中您只引用Test。取决于它实际上应该是什么,如下所示应该可以工作。在运行 Arch Linux 的 Raspberry Pi 上进行了测试。

    你好.h

    typedef enum test { A, B, C, D } test;
    

    hello.pyx

    cpdef enum Test "test": 行的意思是“在 Python 中使用 Test,在 C 中使用 test。参见 Resolving naming conflicts - C name specifications

    cdef extern from "hello.h":
        cpdef enum Test "test":
            A, B, C, D
    
    def t1():
        for t in Test: print(t.value)
    

    setup.py

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(name="hello", ext_modules=cythonize("hello.pyx"))
    

    结果

    Python 3.5.1 (default, Mar  6 2016, 12:32:57)
    [GCC 5.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import hello
    >>> hello.t1()
    0
    1
    2
    3
    

    【讨论】:

    • 我能够成功运行您的示例。不幸的是,枚举名称的错误只是一个错字。我对枚举的 C 声明是错误的。我更新了我的问题,也许你可以再看看。对于上面的示例,我无法重现之前提到的相同错误。原始错误发生在涉及来自真实库的头文件的较大项目中。也许错误是相关的。
    猜你喜欢
    • 2017-02-20
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多