如何在 Cython 中根据 Python 版本有条件地声明代码



我有以下pxd标头,它增强了常规的Python模块:

#!/usr/bin/env python
# coding: utf-8
cimport cython
@cython.locals(media_type=unicode, format=unicode, charset=unicode, render_style=unicode)
cdef class BaseRenderer(object):
    """
    All renderers should extend this class, setting the `media_type`
    and `format` attributes, and override the `.render()` method.
    """
    @cython.locals(indent=int, separators=tuple)
    cpdef object render(self, dict data, accepted_media_type=?, renderer_context=?)
@cython.locals(compact=bool, ensure_ascii=bool, charset=unicode)
cdef class JSONRenderer(BaseRenderer):
    @cython.locals(base_media_type=unicode, params=dict)
    cpdef int get_indent(self, unicode accepted_media_type, dict renderer_context)
@cython.locals(callback_parameter=unicode, default_callback=unicode)
cdef class JSONPRenderer(JSONRenderer):
    cpdef unicode get_callback(self, dict renderer_context)

在 Python 2 中,render() 方法可能会返回字符串、字节或 unicode,但在 Python 3 中,可以保证该方法将返回 unicode。
我无法导入可以在Python/patchlevel.h标头中找到的名为PY_MAJOR_VERSION的 Python 版本#define。我试图使用以下方法包含它:

cdef extern from "patchlevel.h":
  pass

但定义不可用。包含路径已正确设置为 /usr/include/pythonx.x./

如何根据 Python 主要版本在编译时分支此代码?

Python 版本常量在 https://github.com/cython/cython/blob/master/Cython/Includes/cpython/version.pxd

您可以将它们包含在 cimport cpython.version 中,并将它们与编译时 IF 或运行时 if 一起使用。

请注意,如果你想分发C代码而不需要使用编译时安装Cython,IF将使你的代码无法移植,因为生成的代码将只匹配某些python版本。

不幸的是,不可能

将编译时 IF 与 PY_MAJOR_VERSION 或类似一起使用;Cython 只允许文档中描述的那些编译时常量。

最新更新