#cython #sage
#cython #мудрец
Вопрос:
Я пытаюсь создать следующий код в cython для компиляции
from cython_gsl cimport *
import atexit
cdef gsl_rng_type * rng_T = gsl_rng_default
cdef gsl_rng * rng_r
gsl_rng_env_setup()
rng_r = gsl_rng_alloc(rng_T)
@atexit.register
def free_gsl_rng():
gsl_rng_free(rng_r)
Но я всегда получаю сообщение об ошибке
Присвоение значения, отличного от lvalue ‘atexit’
Соответствующий файл .pxd
from cython_gsl cimport *
cdef gsl_rng * rng_r
На самом деле я компилирую это с помощью SageMath 8.7 с помощью
sage setup.py build_ext --inplace
Вот мой setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import cython_gsl
extensions = [
Extension("gsl_rand", ["gsl_rand.pyx"],
libraries=cython_gsl.get_libraries(),
library_dirs=[cython_gsl.get_library_dir()],
include_dirs=[cython_gsl.get_cython_include_dir()]
),
]
setup(
name='Simulation of k-cut on conditional Galton-Watson trees',
cmdclass={'build_ext': build_ext},
include_dirs = [cython_gsl.get_include()],
ext_modules=cythonize(extensions),
)
Full error log here
sage setup.py build_ext --inplace
Compiling gsl_rand.pyx because it changed.
[1/1] Cythonizing gsl_rand.pyx
/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/xing/Dropbox/Research/2017/k-cut/GW/sage/moments/cython-v5/gsl_rand.pxd
tree = Parsing.p_module(s, pxd, full_module_name)
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:65:9: 'GSL_EMAXITER' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:67:9: 'GSL_EROUND' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:69:9: 'GSL_ESING' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:71:9: 'GSL_EDIVERGE' redeclared
warning: gsl_rand.pyx:14:0: Overriding cdef method with def method.
Error compiling Cython file:
------------------------------------------------------------
...
# cython: profile=False
from cython_gsl cimport *
import atexit
^
------------------------------------------------------------
gsl_rand.pyx:5:7: Assignment to non-lvalue 'atexit'
Error compiling Cython file:
------------------------------------------------------------
...
cdef gsl_rng * rng_r
gsl_rng_env_setup()
rng_r = gsl_rng_alloc(rng_T)
@atexit.register
^
------------------------------------------------------------
gsl_rand.pyx:13:0: Object of type 'int (void (*)(void) nogil) nogil' has no attribute 'register'
Traceback (most recent call last):
File "setup.py", line 29, in <module>
ext_modules=cythonize(extensions),
File "/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 1097, in cythonize
cythonize_one(*args)
File "/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 1220, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: gsl_rand.pyx
Комментарии:
1. Для меня это отлично компилируется. Когда вы выполняете команды, чтобы получить эту ошибку, и есть ли еще какой-либо контекст, который с ней связан?
2. Что там внутри
cython_gsl
? Этоimport *
может навлечь на вас неприятности, если не что иное. В самом модуле atexit нет ничего особенного, что касается Cython, поэтому тот факт, что у вас возникли проблемы с ним, в частности, просто случайно.3. Я посмотрел
cython_gsl
, и я не думаю, что проблема специфична и для этого. Пожалуйста, опубликуйте полную трассировку ошибок, так как контекста недостаточно.4. Нет такого
gsl_rand.pxd
, которое давало бы какое-то другое определение? Я немного с подозрением отношусь к «gsl_rand.pyx:14:0: переопределение метода cdef методом def».5. @DavidW да, этого было бы достаточно. Эта более поздняя ошибка дает понять, что именно это и происходит:
gsl_rand.pyx:13:0: Object of type 'int (void (*)(void) nogil) nogil' has no attribute 'register'
. Предполагается, что это функцияatexit
C.
Ответ №1:
atexit
получает cimported с. from cython_gsl cimport *
Похоже, это происходит с линией from libc.stdlib cimport *
. Поэтому это имя конфликтует с модулем Python atexit
. Я думаю, что это хороший пример того, почему from something [c]import *
не рекомендуется, как в вашем коде, так и в коде cython_gsl. Это становится немного более запутанным, потому что Cython имеет два типа имен (для Python и C), поэтому вы получаете странные сообщения об ошибках.
Лучшее решение — либо выполнить cimport cython_gsl
, либо импортировать нужные вам конкретные символы : from cython_gsl cimport gsl_rng, etc
. Не забудьте изменить оба файла pyx и pxd.
Худшим решением является переименование atexit
модуля при его импорте : import atexit as ae
.