Skip to content

Commit ded274a

Browse files
API: partial revert of returning read-only EAs from .array/.values (#63212)
1 parent 787ad72 commit ded274a

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

pandas/core/indexes/base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5023,8 +5023,9 @@ def array(self) -> ExtensionArray:
50235023
from pandas.core.arrays.numpy_ import NumpyExtensionArray
50245024

50255025
array = NumpyExtensionArray(array)
5026-
array = array.view()
5027-
array._readonly = True
5026+
# TODO decide on read-only https://github.com/pandas-dev/pandas/issues/63099
5027+
# array = array.view()
5028+
# array._readonly = True
50285029
return array
50295030

50305031
@property

pandas/core/internals/blocks.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,7 +2387,9 @@ def external_values(values: ArrayLike) -> ArrayLike:
23872387
values.flags.writeable = False
23882388
else:
23892389
# ExtensionArrays
2390-
values = values.view()
2391-
values._readonly = True
2390+
# TODO decide on read-only https://github.com/pandas-dev/pandas/issues/63099
2391+
# values = values.view()
2392+
# values._readonly = True
2393+
pass
23922394

23932395
return values

pandas/core/series.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,9 @@ def _references(self) -> BlockValuesRefs:
821821
@property
822822
def array(self) -> ExtensionArray:
823823
arr = self._mgr.array_values()
824-
arr = arr.view()
825-
arr._readonly = True
824+
# TODO decide on read-only https://github.com/pandas-dev/pandas/issues/63099
825+
# arr = arr.view()
826+
# arr._readonly = True
826827
return arr
827828

828829
def __len__(self) -> int:

pandas/tests/copy_view/test_array.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,21 @@
2525
],
2626
ids=["values", "array", "np.asarray", "np.array"],
2727
)
28-
def test_series_values(method):
28+
def test_series_values(request, method):
2929
ser = Series([1, 2, 3], name="name")
3030
ser_orig = ser.copy()
3131

3232
arr = method(ser)
3333

34+
if request.node.callspec.id == "array":
35+
# https://github.com/pandas-dev/pandas/issues/63099
36+
# .array for now does not return a read-only view
37+
assert arr.flags.writeable is True
38+
# updating the array updates the series
39+
arr[0] = 0
40+
assert ser.iloc[0] == 0
41+
return
42+
3443
# .values still gives a view but is read-only
3544
assert np.shares_memory(arr, get_array(ser, "name"))
3645
assert arr.flags.writeable is False
@@ -109,20 +118,42 @@ def test_series_to_numpy():
109118
@pytest.mark.parametrize(
110119
"method",
111120
[
121+
lambda ser: np.asarray(ser.values),
112122
lambda ser: np.asarray(ser.array),
113123
lambda ser: np.asarray(ser),
114124
lambda ser: np.asarray(ser, dtype="int64"),
115125
lambda ser: np.array(ser, copy=False),
116126
],
117-
ids=["array", "np.asarray", "np.asarray-dtype", "np.array"],
127+
ids=["values", "array", "np.asarray", "np.asarray-dtype", "np.array"],
118128
)
119-
def test_series_values_ea_dtypes(method):
129+
def test_series_values_ea_dtypes(request, method):
120130
ser = Series([1, 2, 3], dtype="Int64")
131+
ser_orig = ser.copy()
132+
121133
arr = method(ser)
122134

135+
if request.node.callspec.id in ("values", "array"):
136+
# https://github.com/pandas-dev/pandas/issues/63099
137+
# .array/values for now does not return a read-only view
138+
assert arr.flags.writeable is True
139+
# updating the array updates the series
140+
arr[0] = 0
141+
assert ser.iloc[0] == 0
142+
return
143+
144+
# conversion to ndarray gives a view but is read-only
123145
assert np.shares_memory(arr, get_array(ser))
124146
assert arr.flags.writeable is False
125147

148+
# mutating series through arr therefore doesn't work
149+
with pytest.raises(ValueError, match="read-only"):
150+
arr[0] = 0
151+
tm.assert_series_equal(ser, ser_orig)
152+
153+
# mutating the series itself still works
154+
ser.iloc[0] = 0
155+
assert ser.values[0] == 0
156+
126157

127158
@pytest.mark.parametrize(
128159
"method",

0 commit comments

Comments
 (0)