From 8683fb6ceea9bfc52bc0a8f5d7943c5725b7b062 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 4 Dec 2023 10:36:36 +0100 Subject: [PATCH 1/2] BUG / CoW: ensure ser[...] returns new object --- pandas/core/series.py | 2 ++ pandas/tests/copy_view/test_indexing.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pandas/core/series.py b/pandas/core/series.py index 6da0351766c91..fad654bbd8a68 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1065,6 +1065,8 @@ def __getitem__(self, key): key = com.apply_if_callable(key, self) if key is Ellipsis: + if using_copy_on_write() or warn_copy_on_write(): + return self.copy(deep=False) return self key_is_scalar = is_scalar(key) diff --git a/pandas/tests/copy_view/test_indexing.py b/pandas/tests/copy_view/test_indexing.py index 72b7aea3709c0..30350a89faef2 100644 --- a/pandas/tests/copy_view/test_indexing.py +++ b/pandas/tests/copy_view/test_indexing.py @@ -845,6 +845,31 @@ def test_series_getitem_slice(backend, using_copy_on_write, warn_copy_on_write): assert s.iloc[0] == 0 +def test_series_getitem_ellipsis(using_copy_on_write, warn_copy_on_write): + # Case: taking a view of a Series using Ellipsis + afterwards modifying the subset + s = Series([1, 2, 3]) + s_orig = s.copy() + + subset = s[...] + assert np.shares_memory(get_array(subset), get_array(s)) + + with tm.assert_cow_warning(warn_copy_on_write): + subset.iloc[0] = 0 + + if using_copy_on_write: + assert not np.shares_memory(get_array(subset), get_array(s)) + + expected = Series([0, 2, 3]) + tm.assert_series_equal(subset, expected) + + if using_copy_on_write: + # original parent series is not modified (CoW) + tm.assert_series_equal(s, s_orig) + else: + # original parent series is actually updated + assert s.iloc[0] == 0 + + @pytest.mark.parametrize( "indexer", [slice(0, 2), np.array([True, True, False]), np.array([0, 1])], From 7416752ae3cb8d76d6f2203e935b8bbd20a67dcb Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 4 Dec 2023 11:17:28 +0100 Subject: [PATCH 2/2] fixup existing test --- pandas/tests/series/indexing/test_indexing.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 0c788b371a03a..c52e47a812183 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -101,14 +101,16 @@ def test_basic_getitem_dt64tz_values(): assert result == expected -def test_getitem_setitem_ellipsis(): +def test_getitem_setitem_ellipsis(using_copy_on_write, warn_copy_on_write): s = Series(np.random.default_rng(2).standard_normal(10)) result = s[...] tm.assert_series_equal(result, s) - s[...] = 5 - assert (result == 5).all() + with tm.assert_cow_warning(warn_copy_on_write): + s[...] = 5 + if not using_copy_on_write: + assert (result == 5).all() @pytest.mark.parametrize(