Opened 6 years ago
#1182 new defect
python old buffer interface deprecated in python 3
Reported by: | pkienzle | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | SasView 5.0.0 |
Component: | SasView | Keywords: | |
Cc: | Work Package: | McSAS Integration Project |
Description
The manual claims that the old buffer interface is deprecated in python 3 and some compilers are issuing warnings to that effect.
May want to update to the new buffer interface.
It's going to be a bit of a pain switching. Instead of just grabbing a pointer inside the object, need to create a Py_buffer object at the start of each wrapper and release it at the end. That means if there are any errors, we can't simply return from the function, but instead have to free all the buffers. If we haven't yet allocated all the buffers when we encounter the error, then we need to only free those for which we already allocated.
Here are some really ugly macros that might work:
#define DECLARE_VECTORS(n) \ Py_buffer VEC_views[n]; \ int VEC_current = 0; #define FREE_VECTORS() \ do { \ int VEC_k = 0; \ while (VEC_k < VEC_current) pyBuffer_Release(VEC_views[VEC_k++]); \ } while (0) // Could save VEC_max in DECLARE_VECTORS and check that we aren't overflowing VEC_views[] #define _VECTOR(obj, buf, len, flags) \ do { \ Py_buffer *view = VEC_views[VEC_current]; int err = PyObject_GetBuffer(obj, view, flags); \ if (err < 0) { FREE_VECTORS(); return NULL; } \ VEC_current++; \ if (sizeof(*buf) != view->itemsize) { \ PyErr_SetString(PyExc_TypeError, "wrong numeric type for vector"); \ FREE_VECTORS(); \ return NULL; \ } \ buf = view->buf; \ len = view->len; \ } while (0) #define INVECTOR(obj, buf, len) _VECTOR(obj, buf, len, PyBUF_SIMPLE|PyBUF_FORMAT) #define OUTVECTOR(obj, buf, len) _VECTOR(obj, buf, len, PyBUF_WRITABLE|PyBUF_FORMAT)
Rather than:
PyObject *in_obj, *out_obj; Py_ssize_t nin, nout; double *in, *out; ... INVECTOR(in_obj,in,nin); OUTVECTOR(in_obj,in,nin); ... if (err) { PyErr_SetString(...); return NULL; } ... return Py_BuildValue(...)
need to do something like:
PyObject *in_obj, *out_obj; Py_ssize_t nin, nout; double *in, *out; DECLARE_VECTORS(2); ... INVECTOR(in_obj,in,nin); OUTVECTOR(in_obj,in,nin); ... if (err) { PyErr_SetString(...); FREE_VECTORS(); return NULL; } ... FREE_VECTORS(); return Py_BuildValue(...)