Description
Since 0.27.1, declaring Py_buffer variables in pure-python mode ceased working. This applies to 0.27.1, 0.27.2 and 0.27.3.
import cython
@cython.locals(pybuf = 'Py_buffer')
def f():
return cython.cast(int, cython.address(pybuf))
print f()
I know this isn't really useful code, but it illustrates the issue with a minimal example. I'm getting this error in actual working (with 0.27.0) code.
When compiling with cython 0.27.2 (and .3), gives:
(cython)claudiofreire@klaumpptophp:~> cython buffer_bug.py
Error compiling Cython file:
------------------------------------------------------------
...
import cython
@cython.locals(pybuf = 'Py_buffer')
^
------------------------------------------------------------
buffer_bug.py:3:23: Not a type
Error compiling Cython file:
------------------------------------------------------------
...
import cython
@cython.locals(pybuf = 'Py_buffer')
def f():
return cython.cast(int, cython.address(pybuf))
^
------------------------------------------------------------
buffer_bug.py:5:43: undeclared name not builtin: pybuf
Error compiling Cython file:
------------------------------------------------------------
...
import cython
@cython.locals(pybuf = 'Py_buffer')
def f():
return cython.cast(int, cython.address(pybuf))
^
------------------------------------------------------------
buffer_bug.py:5:34: Taking address of non-lvalue (type Python object)
In cython 0.27.0, however, it builds correctly, generating the following code:
__pyx_t_1 = __Pyx_PyInt_From_int(((int)(&__pyx_v_pybuf))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
I could find no directly relatable changes in the commit history, but I'm not that familiar with this code, so maybe someone else can figure this out.
To clarify, in non-pure-python mode it works correctly:
from cpython cimport Py_buffer
def f():
cdef Py_buffer pybuf
return <int>&pybuf
print f()
Compiles in all versions.
Adding the cimport to buffer_bug.pxd in pure-python mode doesn't change a thing.
FTR, I realize Py_buffer is unusable in pure python. The use case for this always involves compiled-only code paths:
if cython.compiled:
# do something with Py_buffer
else:
# do it the slower pure-python way