Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Py_buffer builtin struct unusable after 0.27.0 #2046
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:
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
You cannot assign a Py_buffer, as it is a struct intended to be used by passing pointers to it.
Thus, most real-world use cases will not contain assignments.
That said, adding no-op assignments to make it local without actually executing the assignment doesn't work either:
import cython @cython.locals(pybuf = 'Py_buffer') def f(): pybuf = pybuf return cython.cast(int, cython.address(pybuf)) print f()
Using an alternative declaration syntax doesn't work either in 0.27.3, yet it does in 0.27.0:
import cython def f(): pybuf = cython.declare('Py_buffer') return cython.cast(int, cython.address(pybuf)) print f()