在Python 2和Python3上重新编译Cython中的异常

时间:2014-05-07 23:17:08

标签: exception python-3.x cython python-2.x six-python

我有一些目前看起来像

的Cython代码
exc = sys.exc_info()
raise exc[0], exc[1], exc[2]

这不适用于Python3,因为"来自元组"表格不再允许。如果是这个普通的Python代码,我只会使用six.reraise,但这不适合我。 Cython友好的方式是什么,它适用于Python2和Python3?

1 个答案:

答案 0 :(得分:4)

一个很棒的Cython功能是生成的C代码可以针对Python 2或Python 3进行编译。因此,上面的示例将适用于 版本的Python,未经修改。

您可以告诉Cython编译代码,假设Python 2语法和语义(-2参数,默认情况下处于启用状态)或假设Python 3(-3参数)。在任何一种情况下,只要动态组件(导入等)兼容,生成的扩展模块源代码就可以编译并用于Python 2或Python 3。

例如:

def raises_exception():
    raise KeyError("what you doin'?")


def foobar():
    try:
        raises_exception()
    except Exception:
        import sys
        exc = sys.exc_info()
        raise exc[0], exc[1], exc[2]

这是一个可以在Py2或Py3上运行的setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules=cythonize("reraise.pyx"))

我可以在任一版本的Python上运行python setup.py build_ext -i(假设我已经为每个版本安装了cython),并且生成的扩展模块可以正常工作。

$ python setup.py build_ext -i # Py3 python

$ ipython3
Python 3.3.2 (v3.3.2:d047928ae3f6, Oct  4 2013, 15:49:17)
Type "copyright", "credits" or "license" for more information.

IPython 1.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import reraise

In [2]: reraise.foobar()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-9e20eacfd84e> in <module>()
----> 1 reraise.foobar()

/.../reraise.so in reraise.foobar (reraise.c:916)()

/.../reraise.so in reraise.foobar (reraise.c:847)()

/.../reraise.so in reraise.raises_exception (reraise.c:762)()

KeyError: "what you doin'?"

In [3]: