Skip to content

Commit 8994372

Browse files
committed
BUG: Fix bug in putmask for CoW
1 parent 18c4365 commit 8994372

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

pandas/core/internals/managers.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,8 @@ def setitem(self: T, indexer, value) -> T:
384384
return self.apply("setitem", indexer=indexer, value=value)
385385

386386
def putmask(self, mask, new, align: bool = True):
387-
if (
388-
using_copy_on_write()
389-
and self.refs is not None
390-
and not all(ref is None for ref in self.refs)
387+
if using_copy_on_write() and any(
388+
not self._has_no_reference_block(i) for i in range(len(self.blocks))
391389
):
392390
# some reference -> copy full dataframe
393391
# TODO(CoW) this could be optimized to only copy the blocks that would

pandas/tests/copy_view/test_methods.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,3 +700,18 @@ def test_squeeze(using_copy_on_write):
700700
# Without CoW the original will be modified
701701
assert np.shares_memory(series.values, get_array(df, "a"))
702702
assert df.loc[0, "a"] == 0
703+
704+
705+
def test_putmask(using_copy_on_write):
706+
df = DataFrame({"a": [1, 2], "b": 1, "c": 2})
707+
view = df[:]
708+
df_orig = df.copy()
709+
df[df == df] = 5
710+
711+
if using_copy_on_write:
712+
assert not np.shares_memory(get_array(view, "a"), get_array(df, "a"))
713+
tm.assert_frame_equal(view, df_orig)
714+
else:
715+
# Without CoW the original will be modified
716+
assert np.shares_memory(get_array(view, "a"), get_array(df, "a"))
717+
assert view.iloc[0, 0] == 5

0 commit comments

Comments
 (0)