diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 317eca7dc8723..e829d1f4c986b 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -221,6 +221,8 @@ Copy-on-Write improvements - Arithmetic operations that can be inplace, e.g. ``ser *= 2`` will now respect the Copy-on-Write mechanism. +- :meth:`Series.view` will now respect the Copy-on-Write mechanism. + Copy-on-Write can be enabled through one of .. code-block:: python diff --git a/pandas/core/series.py b/pandas/core/series.py index 02ec7208be0cd..ebab641627068 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -840,6 +840,10 @@ def view(self, dtype: Dtype | None = None) -> Series: # implementation res_values = self.array.view(dtype) res_ser = self._constructor(res_values, index=self.index) + if isinstance(res_ser._mgr, SingleBlockManager) and using_copy_on_write(): + blk = res_ser._mgr._block + blk.refs = cast("BlockValuesRefs", self._references) + blk.refs.add_reference(blk) # type: ignore[arg-type] return res_ser.__finalize__(self, method="view") # ---------------------------------------------------------------------- diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index 7429a73717470..00ac06295572f 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -1672,3 +1672,21 @@ def test_transpose_ea_single_column(using_copy_on_write): result = df.T assert not np.shares_memory(get_array(df, "a"), get_array(result, 0)) + + +def test_series_view(using_copy_on_write): + ser = Series([1, 2, 3]) + ser_orig = ser.copy() + + ser2 = ser.view() + assert np.shares_memory(get_array(ser), get_array(ser2)) + if using_copy_on_write: + assert not ser2._mgr._has_no_reference(0) + + ser2.iloc[0] = 100 + + if using_copy_on_write: + tm.assert_series_equal(ser_orig, ser) + else: + expected = Series([100, 2, 3]) + tm.assert_series_equal(ser, expected)