使用pyximport.install时是否有一种干净的方法来抑制Cython的编译器警告?

时间:2016-04-11 19:46:43

标签: python cython

假设我有一个以下结构的简单包:

cython_functions/
    __init__.py
    fib.pyx

fib.pyx包含:

def fib(int n):
    fiblist = [0, 1]
    a, b = fiblist
    while b < n:
        a, b = b, a + b
        fiblist.append(b)
    return fiblist

__init__.py包含:

import pyximport
pyximport.install()
from cython_functions.fib import fib

如果我对fib.pyx进行任何更改,每当我尝试导入包时,都会收到大量编译器警告:

/Users/andfranklin/.pyxbld/temp.macosx-10.6-intel-3.5/pyrex/cython_functions/fib.c:1687:28: warning: unused function '__Pyx_PyObject_AsString' [-Wunused-function]
static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
                           ^
/Users/andfranklin/.pyxbld/temp.macosx-10.6-intel-3.5/pyrex/cython_functions/fib.c:1684:32: warning: unused function '__Pyx_PyUnicode_FromString' [-Wunused-function]
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
                               ^
.
.
.

有没有简单的方法可以抑制它们?在another questions中,他们描述了如何通过.pyxbld文件传递编译器标志。我可以创建包含以下内容的fib.pyxbld

def make_ext(modname, pyxfilename):
    from distutils.extension import Extension
    return Extension(name=modname,
                     sources=[pyxfilename],
                     extra_compile_args=['-w'])

我想避免这种情况。如果我需要创建更多函数,我还需要使用相同的样板创建更多.pyxbld个文件。这看起来过分而且不那么pythonic。

1 个答案:

答案 0 :(得分:5)

我自己也在与这个问题作斗争(很高兴知道我并不孤单!)并且没有找到完美的解决方案。不幸的是,pyximport相当不透明,并且AFAICT在可定制性方面没有太多。

但我确实拥有我认为合理的解决方法,特别是一旦你拥有越来越多的Cython模块,这将有所帮助。

基本上,我有一个模块(让我们说common.cython)包含这样的内容:

from distutils.extension import Extension


DEFAULT_EXTENSION_KWARGS = {
    "extra_compile_args": ["-w"]
}


def pyx_extension(**kwargs):
    for key, value in DEFAULT_EXTENSION_KWARGS.items():
        if key not in kwargs:
            kwargs[key] = value

    return Extension(**kwargs)


def make_ext(modname, pyxfilename):
    return pyx_extension(name=modname, sources=[pyxfilename])

基本上是distutils Extension类的一个瘦包装器,我可以设置一些自定义默认值。

然后在不需要任何自定义构建的pyx模块旁边,我只用一行some_module.pyxbld

from common.cython import make_ext

这很好用,因为.pyxbld文件只是一个python模块,预计会包含带有该签名的make_ext函数。

如果我确实需要为模块自定义.pyxbld,比如我是否需要添加C源文件,它看起来像这样:

def make_ext(modname, pyxfilename):
    from common.cython import pyx_extension

    return pyx_extension(name=modname, sources=[pyxfilename, "my_extra_source.c"])

所以,非常与基本记录的方式不同,但足以满足我的DRY OCD :)希望这会有所帮助,如果你找到更好的方法,请告诉我