Skip to content

Commit 219bc5e

Browse files
authored
CoW: Add warning for update (#56068)
1 parent f331b83 commit 219bc5e

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

pandas/core/frame.py

+8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
InvalidIndexError,
6363
_chained_assignment_method_msg,
6464
_chained_assignment_msg,
65+
_chained_assignment_warning_method_msg,
6566
)
6667
from pandas.util._decorators import (
6768
Appender,
@@ -8849,6 +8850,13 @@ def update(
88498850
ChainedAssignmentError,
88508851
stacklevel=2,
88518852
)
8853+
elif not PYPY and not using_copy_on_write():
8854+
if sys.getrefcount(self) <= REF_COUNT:
8855+
warnings.warn(
8856+
_chained_assignment_warning_method_msg,
8857+
FutureWarning,
8858+
stacklevel=2,
8859+
)
88528860

88538861
from pandas.core.computation import expressions
88548862

pandas/core/series.py

+13
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
InvalidIndexError,
4545
_chained_assignment_method_msg,
4646
_chained_assignment_msg,
47+
_chained_assignment_warning_method_msg,
4748
)
4849
from pandas.util._decorators import (
4950
Appender,
@@ -3560,6 +3561,18 @@ def update(self, other: Series | Sequence | Mapping) -> None:
35603561
ChainedAssignmentError,
35613562
stacklevel=2,
35623563
)
3564+
elif not PYPY and not using_copy_on_write():
3565+
ctr = sys.getrefcount(self)
3566+
ref_count = REF_COUNT
3567+
if hasattr(self, "_cacher"):
3568+
# see https://github.com/pandas-dev/pandas/pull/56060#discussion_r1399245221
3569+
ref_count += 1
3570+
if ctr <= ref_count:
3571+
warnings.warn(
3572+
_chained_assignment_warning_method_msg,
3573+
FutureWarning,
3574+
stacklevel=2,
3575+
)
35633576

35643577
if not isinstance(other, Series):
35653578
other = Series(other)

pandas/tests/copy_view/test_methods.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
Series,
1313
Timestamp,
1414
date_range,
15+
option_context,
1516
period_range,
1617
)
1718
import pandas._testing as tm
@@ -1684,7 +1685,7 @@ def test_get(using_copy_on_write, warn_copy_on_write, key):
16841685
warn = FutureWarning if isinstance(key, str) else None
16851686
else:
16861687
warn = SettingWithCopyWarning if isinstance(key, list) else None
1687-
with pd.option_context("chained_assignment", "warn"):
1688+
with option_context("chained_assignment", "warn"):
16881689
with tm.assert_produces_warning(warn):
16891690
result.iloc[0] = 0
16901691

@@ -1721,7 +1722,7 @@ def test_xs(
17211722
with tm.assert_cow_warning(single_block or axis == 1):
17221723
result.iloc[0] = 0
17231724
else:
1724-
with pd.option_context("chained_assignment", "warn"):
1725+
with option_context("chained_assignment", "warn"):
17251726
with tm.assert_produces_warning(SettingWithCopyWarning):
17261727
result.iloc[0] = 0
17271728

@@ -1756,7 +1757,7 @@ def test_xs_multiindex(
17561757
warn = SettingWithCopyWarning
17571758
else:
17581759
warn = None
1759-
with pd.option_context("chained_assignment", "warn"):
1760+
with option_context("chained_assignment", "warn"):
17601761
with tm.assert_produces_warning(warn):
17611762
result.iloc[0, 0] = 0
17621763

@@ -1813,6 +1814,17 @@ def test_update_chained_assignment(using_copy_on_write):
18131814
with tm.raises_chained_assignment_error():
18141815
df[["a"]].update(ser2.to_frame())
18151816
tm.assert_frame_equal(df, df_orig)
1817+
else:
1818+
with tm.assert_produces_warning(FutureWarning, match="inplace method"):
1819+
df["a"].update(ser2)
1820+
1821+
with tm.assert_produces_warning(FutureWarning, match="inplace method"):
1822+
with option_context("mode.chained_assignment", None):
1823+
df[["a"]].update(ser2.to_frame())
1824+
1825+
with tm.assert_produces_warning(FutureWarning, match="inplace method"):
1826+
with option_context("mode.chained_assignment", None):
1827+
df[df["a"] > 1].update(ser2.to_frame())
18161828

18171829

18181830
def test_inplace_arithmetic_series(using_copy_on_write):

pandas/tests/series/indexing/test_indexing.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ def test_underlying_data_conversion(using_copy_on_write):
295295
df["val"].update(s)
296296
expected = df_original
297297
else:
298-
df["val"].update(s)
298+
with tm.assert_produces_warning(FutureWarning, match="inplace method"):
299+
df["val"].update(s)
299300
expected = DataFrame(
300301
{"a": [1, 2, 3], "b": [1, 2, 3], "c": [1, 2, 3], "val": [0, 1, 0]}
301302
)

pandas/tests/series/methods/test_update.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def test_update(self, using_copy_on_write):
3434
df["c"].update(Series(["foo"], index=[0]))
3535
expected = df_orig
3636
else:
37-
df["c"].update(Series(["foo"], index=[0]))
37+
with tm.assert_produces_warning(FutureWarning, match="inplace method"):
38+
df["c"].update(Series(["foo"], index=[0]))
3839
expected = DataFrame(
3940
[[1, np.nan, "foo"], [3, 2.0, np.nan]], columns=["a", "b", "c"]
4041
)

0 commit comments

Comments
 (0)