Consider the following example:
>>> ser = pd.Series(np.asarray(pa.array([1, 2, 3])), copy=False)
>>> ser
0 1
1 2
2 3
dtype: int64
>>> ser.iloc[0] = 10
...
File ~/scipy/repos/pandas/pandas/core/internals/blocks.py:1139, in Block.setitem(self, indexer, value)
1137 casted = casted[0, ...]
1138 try:
-> 1139 values[indexer] = casted
1140 except (TypeError, ValueError) as err:
1141 if is_list_like(casted):
ValueError: assignment destination is read-only
Here I create a pandas Series backed by a read-only numpy array somewhat manually through conversion from pyarrow and an explicit copy=False
, but you can also run into this in certain cases when converting from Arrow-like data to pandas (depending on the exact conversion method). And with CoW we are now returning read-only arrays from .values
etc, and so this might also become more common in non-Arrow related code.
From a user perspective, you have a pandas Series, and in general we allow to mutate a Series. So should this just always work? (regardless of how the Series was created, which is not necessarily always under the user control)
If this happens, we could automatically copy the array inplace in the Series to let the high-level pandas setitem operation work as expected (at the cost of an unexpected delayed copy, but this is similar as with CoW)
Comment From: jbrockmendel
if i wanted to prevent mutation, setting the underlying array to readonly would be how i would do it
Comment From: jorisvandenbossche
While that is certainly a trick that sometimes works, I would consider that relying on internal details, as we in the past copied quite generously, and now with CoW might do a copy before performing the setitem, which makes this not a very reliable trick. For example:
>>> ser = pd.Series(np.asarray(pa.array([1, 2, 3])), copy=False)
>>> ser2 = ser[:2]
>>> ser.iloc[0] = 10
>>> ser
0 10
1 2
2 3
dtype: int64
Just because there was a view on the data, now this setitem does not raise an error.
Comment From: jbrockmendel
fair enough. i guess id be fine either with a silent copy of with raising so the user can copy themselves.