Skip to content

Commit b84ac0e

Browse files
BUG(CoW): also raise for chained assignment for .at / .iat (#62074)
1 parent 4257ad6 commit b84ac0e

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

pandas/core/indexing.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,6 +2581,12 @@ def __getitem__(self, key):
25812581
return super().__getitem__(key)
25822582

25832583
def __setitem__(self, key, value) -> None:
2584+
if not PYPY:
2585+
if sys.getrefcount(self.obj) <= 2:
2586+
warnings.warn(
2587+
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
2588+
)
2589+
25842590
if self.ndim == 2 and not self._axes_are_unique:
25852591
# GH#33041 fall back to .loc
25862592
if not isinstance(key, tuple) or not all(is_scalar(x) for x in key):
@@ -2605,6 +2611,15 @@ def _convert_key(self, key):
26052611
raise ValueError("iAt based indexing can only have integer indexers")
26062612
return key
26072613

2614+
def __setitem__(self, key, value) -> None:
2615+
if not PYPY:
2616+
if sys.getrefcount(self.obj) <= 2:
2617+
warnings.warn(
2618+
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
2619+
)
2620+
2621+
return super().__setitem__(key, value)
2622+
26082623

26092624
def _tuplify(ndim: int, loc: Hashable) -> tuple[Hashable | slice, ...]:
26102625
"""

pandas/tests/copy_view/test_chained_assignment_deprecation.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,71 @@ def test_frame_setitem(indexer):
3131

3232
with tm.raises_chained_assignment_error():
3333
df[0:3][indexer] = 10
34+
35+
36+
@pytest.mark.parametrize(
37+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
38+
)
39+
def test_series_iloc_setitem(indexer):
40+
df = DataFrame({"a": [1, 2, 3], "b": 1})
41+
42+
with tm.raises_chained_assignment_error():
43+
df["a"].iloc[indexer] = 0
44+
45+
46+
@pytest.mark.parametrize(
47+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
48+
)
49+
def test_frame_iloc_setitem(indexer):
50+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
51+
52+
with tm.raises_chained_assignment_error():
53+
df[0:3].iloc[indexer] = 10
54+
55+
56+
@pytest.mark.parametrize(
57+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
58+
)
59+
def test_series_loc_setitem(indexer):
60+
df = DataFrame({"a": [1, 2, 3], "b": 1})
61+
62+
with tm.raises_chained_assignment_error():
63+
df["a"].loc[indexer] = 0
64+
65+
66+
@pytest.mark.parametrize(
67+
"indexer", [0, [0, 1], (0, "a"), slice(0, 2), np.array([True, False, True])]
68+
)
69+
def test_frame_loc_setitem(indexer):
70+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
71+
72+
with tm.raises_chained_assignment_error():
73+
df[0:3].loc[indexer] = 10
74+
75+
76+
def test_series_at_setitem():
77+
df = DataFrame({"a": [1, 2, 3], "b": 1})
78+
79+
with tm.raises_chained_assignment_error():
80+
df["a"].at[0] = 0
81+
82+
83+
def test_frame_at_setitem():
84+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
85+
86+
with tm.raises_chained_assignment_error():
87+
df[0:3].at[0, "a"] = 10
88+
89+
90+
def test_series_iat_setitem():
91+
df = DataFrame({"a": [1, 2, 3], "b": 1})
92+
93+
with tm.raises_chained_assignment_error():
94+
df["a"].iat[0] = 0
95+
96+
97+
def test_frame_iat_setitem():
98+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
99+
100+
with tm.raises_chained_assignment_error():
101+
df[0:3].iat[0, 0] = 10

0 commit comments

Comments
 (0)