Skip to content

Commit 5165102

Browse files
CoW warning mode: enable chained assignment warning for DataFrame setitem in default mode (#56230)
1 parent 7c6d26f commit 5165102

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

pandas/core/frame.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -4230,15 +4230,14 @@ def __setitem__(self, key, value) -> None:
42304230
warnings.warn(
42314231
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
42324232
)
4233-
# elif not PYPY and not using_copy_on_write():
4234-
elif not PYPY and warn_copy_on_write():
4235-
if sys.getrefcount(self) <= 3: # and (
4236-
# warn_copy_on_write()
4237-
# or (
4238-
# not warn_copy_on_write()
4239-
# and self._mgr.blocks[0].refs.has_reference()
4240-
# )
4241-
# ):
4233+
elif not PYPY and not using_copy_on_write():
4234+
if sys.getrefcount(self) <= 3 and (
4235+
warn_copy_on_write()
4236+
or (
4237+
not warn_copy_on_write()
4238+
and any(b.refs.has_reference() for b in self._mgr.blocks) # type: ignore[union-attr]
4239+
)
4240+
):
42424241
warnings.warn(
42434242
_chained_assignment_warning_msg, FutureWarning, stacklevel=2
42444243
)

pandas/tests/copy_view/test_chained_assignment_deprecation.py

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import numpy as np
22
import pytest
33

4-
from pandas.errors import ChainedAssignmentError
4+
from pandas.errors import (
5+
ChainedAssignmentError,
6+
SettingWithCopyWarning,
7+
)
58

6-
from pandas import DataFrame
9+
from pandas import (
10+
DataFrame,
11+
option_context,
12+
)
713
import pandas._testing as tm
814

915

@@ -85,3 +91,17 @@ def test_series_setitem(indexer, using_copy_on_write):
8591
else:
8692
assert record[0].category == FutureWarning
8793
assert "ChainedAssignmentError" in record[0].message.args[0]
94+
95+
96+
@pytest.mark.filterwarnings("ignore::pandas.errors.SettingWithCopyWarning")
97+
@pytest.mark.parametrize(
98+
"indexer", ["a", ["a", "b"], slice(0, 2), np.array([True, False, True])]
99+
)
100+
def test_frame_setitem(indexer, using_copy_on_write):
101+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
102+
103+
extra_warnings = () if using_copy_on_write else (SettingWithCopyWarning,)
104+
105+
with option_context("chained_assignment", "warn"):
106+
with tm.raises_chained_assignment_error(extra_warnings=extra_warnings):
107+
df[0:3][indexer] = 10

pandas/tests/indexing/multiindex/test_setitem.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ def test_frame_setitem_copy_raises(
548548
else:
549549
msg = "A value is trying to be set on a copy of a slice from a DataFrame"
550550
with pytest.raises(SettingWithCopyError, match=msg):
551-
df["foo"]["one"] = 2
551+
with tm.raises_chained_assignment_error():
552+
df["foo"]["one"] = 2
552553

553554

554555
def test_frame_setitem_copy_no_write(
@@ -563,7 +564,8 @@ def test_frame_setitem_copy_no_write(
563564
else:
564565
msg = "A value is trying to be set on a copy of a slice from a DataFrame"
565566
with pytest.raises(SettingWithCopyError, match=msg):
566-
df["foo"]["one"] = 2
567+
with tm.raises_chained_assignment_error():
568+
df["foo"]["one"] = 2
567569

568570
result = df
569571
tm.assert_frame_equal(result, expected)

pandas/tests/indexing/test_chaining_and_caching.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,8 @@ def test_detect_chained_assignment_undefined_column(
452452
df.iloc[0:5]["group"] = "a"
453453
else:
454454
with pytest.raises(SettingWithCopyError, match=msg):
455-
df.iloc[0:5]["group"] = "a"
455+
with tm.raises_chained_assignment_error():
456+
df.iloc[0:5]["group"] = "a"
456457

457458
@pytest.mark.arm_slow
458459
def test_detect_chained_assignment_changing_dtype(

0 commit comments

Comments
 (0)