Skip to content

Commit

Permalink
CoW warning mode: enable chained assignment warning for DataFrame set…
Browse files Browse the repository at this point in the history
…item in default mode (#56230)
  • Loading branch information
jorisvandenbossche authored Dec 4, 2023
1 parent 7c6d26f commit 5165102
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
17 changes: 8 additions & 9 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4230,15 +4230,14 @@ def __setitem__(self, key, value) -> None:
warnings.warn(
_chained_assignment_msg, ChainedAssignmentError, stacklevel=2
)
# elif not PYPY and not using_copy_on_write():
elif not PYPY and warn_copy_on_write():
if sys.getrefcount(self) <= 3: # and (
# warn_copy_on_write()
# or (
# not warn_copy_on_write()
# and self._mgr.blocks[0].refs.has_reference()
# )
# ):
elif not PYPY and not using_copy_on_write():
if sys.getrefcount(self) <= 3 and (
warn_copy_on_write()
or (
not warn_copy_on_write()
and any(b.refs.has_reference() for b in self._mgr.blocks) # type: ignore[union-attr]
)
):
warnings.warn(
_chained_assignment_warning_msg, FutureWarning, stacklevel=2
)
Expand Down
24 changes: 22 additions & 2 deletions pandas/tests/copy_view/test_chained_assignment_deprecation.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import numpy as np
import pytest

from pandas.errors import ChainedAssignmentError
from pandas.errors import (
ChainedAssignmentError,
SettingWithCopyWarning,
)

from pandas import DataFrame
from pandas import (
DataFrame,
option_context,
)
import pandas._testing as tm


Expand Down Expand Up @@ -85,3 +91,17 @@ def test_series_setitem(indexer, using_copy_on_write):
else:
assert record[0].category == FutureWarning
assert "ChainedAssignmentError" in record[0].message.args[0]


@pytest.mark.filterwarnings("ignore::pandas.errors.SettingWithCopyWarning")
@pytest.mark.parametrize(
"indexer", ["a", ["a", "b"], slice(0, 2), np.array([True, False, True])]
)
def test_frame_setitem(indexer, using_copy_on_write):
df = DataFrame({"a": [1, 2, 3, 4, 5], "b": 1})

extra_warnings = () if using_copy_on_write else (SettingWithCopyWarning,)

with option_context("chained_assignment", "warn"):
with tm.raises_chained_assignment_error(extra_warnings=extra_warnings):
df[0:3][indexer] = 10
6 changes: 4 additions & 2 deletions pandas/tests/indexing/multiindex/test_setitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,8 @@ def test_frame_setitem_copy_raises(
else:
msg = "A value is trying to be set on a copy of a slice from a DataFrame"
with pytest.raises(SettingWithCopyError, match=msg):
df["foo"]["one"] = 2
with tm.raises_chained_assignment_error():
df["foo"]["one"] = 2


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

result = df
tm.assert_frame_equal(result, expected)
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/indexing/test_chaining_and_caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ def test_detect_chained_assignment_undefined_column(
df.iloc[0:5]["group"] = "a"
else:
with pytest.raises(SettingWithCopyError, match=msg):
df.iloc[0:5]["group"] = "a"
with tm.raises_chained_assignment_error():
df.iloc[0:5]["group"] = "a"

@pytest.mark.arm_slow
def test_detect_chained_assignment_changing_dtype(
Expand Down

0 comments on commit 5165102

Please sign in to comment.