Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python old buffer interface deprecated in python 3 (Trac #1182) #1218

Open
pkienzle opened this issue Mar 30, 2019 · 0 comments
Open

python old buffer interface deprecated in python 3 (Trac #1182) #1218

pkienzle opened this issue Mar 30, 2019 · 0 comments
Labels
Defect Bug or undesirable behaviour McSAS McSAS Integration Project Minor Small job
Milestone

Comments

@pkienzle
Copy link
Contributor

pkienzle commented Mar 30, 2019

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(...)

Migrated from http://trac.sasview.org/ticket/1182

{
    "status": "new",
    "changetime": "2018-09-24T21:40:45",
    "_ts": "2018-09-24 21:40:45.160966+00:00",
    "description": "The manual claims that the old buffer interface is deprecated in python 3 and some compilers are issuing warnings to that effect.\n\nMay want to update to the new buffer interface.\n\nIt'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.\n\nHere are some really ugly macros that might work:\n{{{\n#define DECLARE_VECTORS(n) \\\n    Py_buffer VEC_views[n]; \\\n    int VEC_current = 0;\n\n#define FREE_VECTORS() \\\n    do { \\\n        int VEC_k = 0; \\\n        while (VEC_k < VEC_current) pyBuffer_Release(VEC_views[VEC_k++]); \\\n     } while (0)\n\n// Could save VEC_max in DECLARE_VECTORS and check that we aren't overflowing VEC_views[]\n#define _VECTOR(obj, buf, len, flags) \\\n    do { \\\n        Py_buffer *view = VEC_views[VEC_current];\n        int err = PyObject_GetBuffer(obj, view, flags); \\\n        if (err < 0) { FREE_VECTORS(); return NULL; } \\\n        VEC_current++; \\\n        if (sizeof(*buf) != view->itemsize) { \\\n            PyErr_SetString(PyExc_TypeError, \"wrong numeric type for vector\"); \\\n            FREE_VECTORS(); \\\n            return NULL; \\\n        } \\\n        buf = view->buf; \\\n        len = view->len; \\\n    } while (0)\n\n#define INVECTOR(obj, buf, len) _VECTOR(obj, buf, len, PyBUF_SIMPLE|PyBUF_FORMAT)\n#define OUTVECTOR(obj, buf, len) _VECTOR(obj, buf, len, PyBUF_WRITABLE|PyBUF_FORMAT)\n}}}\n\n\nRather than:\n{{{\n    PyObject *in_obj, *out_obj;\n    Py_ssize_t nin, nout;\n    double *in, *out;\n    ...\n    INVECTOR(in_obj,in,nin);\n    OUTVECTOR(in_obj,in,nin);\n    ...\n    if (err) {\n        PyErr_SetString(...);\n        return NULL;\n    }\n    ...\n    return Py_BuildValue(...)\n}}}\nneed to do something like:\n{{{\n    PyObject *in_obj, *out_obj;\n    Py_ssize_t nin, nout;\n    double *in, *out;\n    DECLARE_VECTORS(2);\n    ...\n    INVECTOR(in_obj,in,nin);\n    OUTVECTOR(in_obj,in,nin);\n    ... \n    if (err) {\n        PyErr_SetString(...);\n        FREE_VECTORS();\n        return NULL;\n    }\n    ...\n    FREE_VECTORS();\n    return Py_BuildValue(...)\n}}}\n",
    "reporter": "pkienzle",
    "cc": "",
    "resolution": "",
    "workpackage": "McSAS Integration Project",
    "time": "2018-09-24T21:40:45",
    "component": "SasView",
    "summary": "python old buffer interface deprecated in python 3",
    "priority": "minor",
    "keywords": "",
    "milestone": "SasView 5.0.0",
    "owner": "",
    "type": "defect"
}
@pkienzle pkienzle added this to the SasView 5.0.0 milestone Mar 30, 2019
@pkienzle pkienzle added Defect Bug or undesirable behaviour Incomplete Migration McSAS McSAS Integration Project Minor Small job labels Mar 30, 2019
@rozyczko rozyczko modified the milestones: SasView 5.0.0, SasView 5.1.0 May 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Bug or undesirable behaviour McSAS McSAS Integration Project Minor Small job
Projects
None yet
Development

No branches or pull requests

4 participants