Search code examples
python-c-api

Creating a PyMemoryView with a specific format


I am exposing a PyMemoryView in C on a set of data, like so:

PyMemoryView_FromMemory((char *)ibuf->rect, pixels * sizeof(uint), PyBUF_WRITE);

That data is floating-point data, however, so attempting to do this:

mv = get_my_memory_view()
mv[0] = 3.141

yields the following error:

TypeError: memoryview: invalid type for format 'B'

This is, of course, because the memoryview assumes the underlying data to be byte data, not float. How would I ensure that the memoryview returned from my module has a float specifier?


Solution

  • The easiest way would probably be to use the cast method of the memoryview to get a new memoryview with the correct format. There isn't a direct C-API method to do it, so just call it like any other Python method:

    mview_double = PyObject_CallMethod(mview_bytes, "cast", "s", "d");
    

    this assumes double data - if it's float data then you should change the "d".


    In the original call to PyMemoryView_FromMemory I think pixels * sizeof(uint) is wrong since you've told us the data-type is a floating-point type. Maybe pixels*sizeof(ibuf->rect[0])?