From 142725195ead584a5dd79b3b62cedd730ab241f8 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:27:23 +0100 Subject: [PATCH 1/3] CoW: Avoid warning in case of expansion --- pandas/core/internals/managers.py | 17 ++++++++++++----- pandas/tests/frame/indexing/test_indexing.py | 4 +--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index a221d02b75bb2..cc88312d5b58f 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -1325,16 +1325,16 @@ def column_setitem( This is a method on the BlockManager level, to avoid creating an intermediate Series at the DataFrame level (`s = df[loc]; s[idx] = value`) """ + needs_to_warn = False if warn_copy_on_write() and not self._has_no_reference(loc): if not isinstance( self.blocks[self.blknos[loc]].values, (ArrowExtensionArray, ArrowStringArray), ): - warnings.warn( - COW_WARNING_GENERAL_MSG, - FutureWarning, - stacklevel=find_stack_level(), - ) + # We might raise if we are in an expansion case, so defer + # warning till we actually updated + needs_to_warn = True + elif using_copy_on_write() and not self._has_no_reference(loc): blkno = self.blknos[loc] # Split blocks to only copy the column we want to modify @@ -1358,6 +1358,13 @@ def column_setitem( new_mgr = col_mgr.setitem((idx,), value) self.iset(loc, new_mgr._block.values, inplace=True) + if needs_to_warn: + warnings.warn( + COW_WARNING_GENERAL_MSG, + FutureWarning, + stacklevel=find_stack_level(), + ) + def insert(self, loc: int, item: Hashable, value: ArrayLike, refs=None) -> None: """ Insert item at selected position. diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index dfb4a3092789a..40c6b8e180c5b 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -1397,9 +1397,7 @@ def test_iloc_setitem_enlarge_no_warning(self, warn_copy_on_write): df = DataFrame(columns=["a", "b"]) expected = df.copy() view = df[:] - # TODO(CoW-warn) false positive: shouldn't warn in case of enlargement? - with tm.assert_produces_warning(FutureWarning if warn_copy_on_write else None): - df.iloc[:, 0] = np.array([1, 2], dtype=np.float64) + df.iloc[:, 0] = np.array([1, 2], dtype=np.float64) tm.assert_frame_equal(view, expected) def test_loc_internals_not_updated_correctly(self): From 77f7aa434f80c6bffe9c97ddd56669127cd2e8d8 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:05:41 +0100 Subject: [PATCH 2/3] Fixup --- pandas/conftest.py | 1 + pandas/tests/copy_view/test_indexing.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/conftest.py b/pandas/conftest.py index 003474b57c8e1..d17468d7ca67f 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1905,6 +1905,7 @@ def warn_copy_on_write() -> bool: """ Fixture to check if Copy-on-Write is enabled. """ + pd.options.mode.copy_on_write = "warn" return ( pd.options.mode.copy_on_write == "warn" and _get_option("mode.data_manager", silent=True) == "block" diff --git a/pandas/tests/copy_view/test_indexing.py b/pandas/tests/copy_view/test_indexing.py index 33b8ce218f029..6f3850ab64daa 100644 --- a/pandas/tests/copy_view/test_indexing.py +++ b/pandas/tests/copy_view/test_indexing.py @@ -1145,13 +1145,12 @@ def test_set_value_copy_only_necessary_column( view = df[:] if val == "a" and indexer[0] != slice(None): - # TODO(CoW-warn) assert the FutureWarning for CoW is also raised with tm.assert_produces_warning( FutureWarning, match="Setting an item of incompatible dtype is deprecated" ): indexer_func(df)[indexer] = val else: - with tm.assert_cow_warning(warn_copy_on_write): + with tm.assert_cow_warning(warn_copy_on_write and val == 100): indexer_func(df)[indexer] = val if using_copy_on_write: From 86c9946e3cef7765ec50107d20434639c2e693f5 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:06:19 +0100 Subject: [PATCH 3/3] Fixup --- pandas/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/conftest.py b/pandas/conftest.py index d17468d7ca67f..003474b57c8e1 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1905,7 +1905,6 @@ def warn_copy_on_write() -> bool: """ Fixture to check if Copy-on-Write is enabled. """ - pd.options.mode.copy_on_write = "warn" return ( pd.options.mode.copy_on_write == "warn" and _get_option("mode.data_manager", silent=True) == "block"