-1

I am trying to make the following code in cython to compile

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)

But I always get the error

Assignment to non-lvalue 'atexit'

Corresponding .pxd file

from cython_gsl cimport *

cdef gsl_rng * rng_r

I am actually compiling this with SageMath 8.7 by

sage setup.py build_ext --inplace

Here is my 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
faceclean
  • 3,781
  • 8
  • 39
  • 58
  • 1
    This compiles fine for me. When commands are you running to get this error and is there any more context that comes with it? – DavidW Apr 19 '19 at 10:30
  • What's in `cython_gsl`? Your `import *` might be getting you into trouble if nothing else. There's nothing special about the atexit module itself as far as Cython is concerned, so the fact that you're having a problem with it in particular is just happenstance. – Iguananaut Apr 19 '19 at 13:09
  • I looked at `cython_gsl` and I don't think the problem is specific to that either. Please post the *full* error trace as there is not enough context. – Iguananaut Apr 19 '19 at 13:18
  • 1
    There isn't a `gsl_rand.pxd` that provides some different definition? I'm a bit suspicious of "gsl_rand.pyx:14:0: Overriding cdef method with def method." – DavidW Apr 19 '19 at 13:42
  • @DavidW Yes, there is one. – faceclean Apr 19 '19 at 13:48
  • 1
    @DavidW yes that would do it. This later error makes it clear that's what's happening: `gsl_rand.pyx:13:0: Object of type 'int (void (*)(void) nogil) nogil' has no attribute 'register'`. It is assuming `atexit` is a C function. – Iguananaut Apr 19 '19 at 15:09

1 Answers1

0

atexit is getting cimported with from cython_gsl cimport *. This appears to happen with the line from libc.stdlib cimport *. This name therefore conflicts with the Python atexit module. I think this is a good example of why from something [c]import * is not recommended, both in your code and in cython_gsl's code. It gets slightly more confusing because Cython has two types of names (for Python and C) so you get odd error messages.

The best solution is to either do cimport cython_gsl or to cimport the specific symbols you need: from cython_gsl cimport gsl_rng, etc. Remember to change both the pyx and pxd file.

The worse workround is to rename the atexit module when you import it: import atexit as ae.

DavidW
  • 29,336
  • 6
  • 55
  • 86