pythonnumpy

when set ndarray.data=x, says attribute 'data' of 'numpy.ndarray' objects is not writable


import numpy as np
import ctypes
img = np.empty((10, 10), dtype=np.uint8)
a=(ctypes.c_uint8 * 100)()
img.data=a

runnable code in py3.8
but says not writable in py3.9:
Traceback (most recent call last):
File "", line 1, in
AttributeError: attribute 'data' of 'numpy.ndarray' objects is not writable

i check img.flags in py3.9:

img.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False

Solution

  • Deprecation details

    What you are seeing is a difference between numpy 1.x and numpy 2.x, rather than between python versions.

    With numpy 1.24.3, I get the warning

    DeprecationWarning: Assigning the 'data' attribute is an inherently unsafe operation and will be removed in the future.

    And with numpy 2.0.1, they've acted on that deprecation planned and turned the warning into the error you see:

    AttributeError: attribute 'data' of 'numpy.ndarray' objects is not writable

    This tells me that code was probably never meant to be used and worked accidentally, but eventually got deprecated as the warning says.

    References

    That change is documented under Expired deprecations in the Numpy 2.0.0 release notes.

    The ability to write to ndarray's data attribute was deprecated in numpy 1.12.0 released back in 2017.

    Workarounds

    As shown, your code just sets all the values to zero, if that was the requirement this would work:

    img = np.zeros((10,10), dtype=np.uint8)
    

    In the comments you say a actually arrives externally. You could use np.full() like this instead:

    img = np.full((100,), a).reshape((10,10))
    

    I didn't find a constructor that create a 2-d array from a 1-d fill value, but reshaping like that works.

    Array creation routines documents all the recommended ways to create arrays based on different requirements.