Skip to content

Commit b2ab83a

Browse files
BUG(CoW): also raise for chained assignment for .at / .iat (pandas-dev#62074)
1 parent c4fa611 commit b2ab83a

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

pandas/core/indexing.py

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

25772577
def __setitem__(self, key, value) -> None:
2578+
if not PYPY:
2579+
if sys.getrefcount(self.obj) <= 2:
2580+
warnings.warn(
2581+
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
2582+
)
2583+
25782584
if self.ndim == 2 and not self._axes_are_unique:
25792585
# GH#33041 fall back to .loc
25802586
if not isinstance(key, tuple) or not all(is_scalar(x) for x in key):
@@ -2599,6 +2605,15 @@ def _convert_key(self, key):
25992605
raise ValueError("iAt based indexing can only have integer indexers")
26002606
return key
26012607

2608+
def __setitem__(self, key, value) -> None:
2609+
if not PYPY:
2610+
if sys.getrefcount(self.obj) <= 2:
2611+
warnings.warn(
2612+
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
2613+
)
2614+
2615+
return super().__setitem__(key, value)
2616+
26022617

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

pandas/tests/copy_view/test_chained_assignment_deprecation.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,79 @@ def test_frame_setitem(indexer, using_copy_on_write):
172172
with option_context("chained_assignment", "warn"):
173173
with tm.raises_chained_assignment_error(extra_warnings=extra_warnings):
174174
df[0:3][indexer] = 10
175+
176+
177+
@pytest.mark.parametrize(
178+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
179+
)
180+
def test_series_iloc_setitem(indexer, using_copy_on_write):
181+
df = DataFrame({"a": [1, 2, 3], "b": 1})
182+
183+
if using_copy_on_write:
184+
with tm.raises_chained_assignment_error():
185+
df["a"].iloc[indexer] = 0
186+
187+
188+
@pytest.mark.parametrize(
189+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
190+
)
191+
def test_frame_iloc_setitem(indexer, using_copy_on_write):
192+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
193+
194+
if using_copy_on_write:
195+
with tm.raises_chained_assignment_error():
196+
df[0:3].iloc[indexer] = 10
197+
198+
199+
@pytest.mark.parametrize(
200+
"indexer", [0, [0, 1], slice(0, 2), np.array([True, False, True])]
201+
)
202+
def test_series_loc_setitem(indexer, using_copy_on_write):
203+
df = DataFrame({"a": [1, 2, 3], "b": 1})
204+
205+
if using_copy_on_write:
206+
with tm.raises_chained_assignment_error():
207+
df["a"].loc[indexer] = 0
208+
209+
210+
@pytest.mark.parametrize(
211+
"indexer", [0, [0, 1], (0, "a"), slice(0, 2), np.array([True, False, True])]
212+
)
213+
def test_frame_loc_setitem(indexer, using_copy_on_write):
214+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
215+
216+
if using_copy_on_write:
217+
with tm.raises_chained_assignment_error():
218+
df[0:3].loc[indexer] = 10
219+
220+
221+
def test_series_at_setitem(using_copy_on_write):
222+
df = DataFrame({"a": [1, 2, 3], "b": 1})
223+
224+
if using_copy_on_write:
225+
with tm.raises_chained_assignment_error():
226+
df["a"].at[0] = 0
227+
228+
229+
def test_frame_at_setitem(using_copy_on_write):
230+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
231+
232+
if using_copy_on_write:
233+
with tm.raises_chained_assignment_error():
234+
df[0:3].at[0, "a"] = 10
235+
236+
237+
def test_series_iat_setitem(using_copy_on_write):
238+
df = DataFrame({"a": [1, 2, 3], "b": 1})
239+
240+
if using_copy_on_write:
241+
with tm.raises_chained_assignment_error():
242+
df["a"].iat[0] = 0
243+
244+
245+
def test_frame_iat_setitem(using_copy_on_write):
246+
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})
247+
248+
if using_copy_on_write:
249+
with tm.raises_chained_assignment_error():
250+
df[0:3].iat[0, 0] = 10

0 commit comments

Comments
 (0)