Есть ли чистый способ подавить предупреждения компилятора от Cython при использовании pyximport.install?

Скажем, у меня есть простой пакет следующей структуры:

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) {
                               ^
.
.
.

Есть ли простой способ подавить их? В других вопросах описывается, как передавать флаги компилятора через файл .pyxbld. Возможно создание fib.pyxbld, содержащее следующее:

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

Я бы хотел этого избежать. Если мне нужно создать больше функций, мне также нужно создать больше файлов .pyxbld с тем же шаблоном. Это кажется чрезмерным и непифовым.

Ответ 1

Я сам боролся с этой тобой (рад узнать, что я не один!) и не нашел идеального решения. К сожалению, 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, которые не нуждаются в каком-либо настраиваемом здании, я помещаю a 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:) Надеюсь, это поможет, и, пожалуйста, позвольте я знаю, если вы найдете лучший способ.