Skip to content

Commit 6a04186

Browse files
jorisvandenbosschephofl
authored andcommitted
CoW warning mode: clean-up some TODOs (pandas-dev#56080)
1 parent d0d4258 commit 6a04186

File tree

6 files changed

+26
-14
lines changed

6 files changed

+26
-14
lines changed

pandas/tests/copy_view/test_core_functionalities.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ def test_setitem_with_view_invalidated_does_not_copy(
5151
df["b"] = 100
5252
arr = get_array(df, "a")
5353
view = None # noqa: F841
54-
# TODO(CoW-warn) false positive?
54+
# TODO(CoW-warn) false positive? -> block gets split because of `df["b"] = 100`
55+
# which introduces additional refs, even when those of `view` go out of scopes
5556
with tm.assert_cow_warning(warn_copy_on_write):
5657
df.iloc[0, 0] = 100
5758
if using_copy_on_write:

pandas/tests/copy_view/test_indexing.py

+22-6
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ def test_subset_column_slice(
163163
subset.iloc[0, 0] = 0
164164
assert not np.shares_memory(get_array(subset, "b"), get_array(df, "b"))
165165
elif warn_copy_on_write:
166-
# TODO(CoW-warn) should warn
167166
with tm.assert_cow_warning(single_block):
168167
subset.iloc[0, 0] = 0
169168
else:
@@ -334,7 +333,6 @@ def test_subset_set_with_row_indexer(
334333
):
335334
pytest.skip("setitem with labels selects on columns")
336335

337-
# TODO(CoW-warn) should warn
338336
if using_copy_on_write:
339337
indexer_si(subset)[indexer] = 0
340338
elif warn_copy_on_write:
@@ -369,7 +367,8 @@ def test_subset_set_with_mask(backend, using_copy_on_write, warn_copy_on_write):
369367

370368
mask = subset > 3
371369

372-
# TODO(CoW-warn) should warn
370+
# TODO(CoW-warn) should warn -> mask is a DataFrame, which ends up going through
371+
# DataFrame._where(..., inplace=True)
373372
if using_copy_on_write or warn_copy_on_write:
374373
subset[mask] = 0
375374
else:
@@ -403,7 +402,6 @@ def test_subset_set_column(backend, using_copy_on_write, warn_copy_on_write):
403402
else:
404403
arr = pd.array([10, 11], dtype="Int64")
405404

406-
# TODO(CoW-warn) should warn
407405
if using_copy_on_write or warn_copy_on_write:
408406
subset["a"] = arr
409407
else:
@@ -512,7 +510,6 @@ def test_subset_set_columns(backend, using_copy_on_write, warn_copy_on_write, dt
512510
df_orig = df.copy()
513511
subset = df[1:3]
514512

515-
# TODO(CoW-warn) should warn
516513
if using_copy_on_write or warn_copy_on_write:
517514
subset[["a", "c"]] = 0
518515
else:
@@ -877,6 +874,8 @@ def test_series_subset_set_with_indexer(
877874
)
878875
if warn_copy_on_write:
879876
# TODO(CoW-warn) should also warn for setting with mask
877+
# -> Series.__setitem__ with boolean mask ends up using Series._set_values
878+
# or Series._where depending on value being set
880879
with tm.assert_cow_warning(
881880
not is_mask, raise_on_extra_warnings=warn is not None
882881
):
@@ -1006,6 +1005,7 @@ def test_column_as_series_set_with_upcast(
10061005
s[0] = "foo"
10071006
expected = Series([1, 2, 3], name="a")
10081007
elif using_copy_on_write or warn_copy_on_write or using_array_manager:
1008+
# TODO(CoW-warn) assert the FutureWarning for CoW is also raised
10091009
with tm.assert_produces_warning(FutureWarning, match="incompatible dtype"):
10101010
s[0] = "foo"
10111011
expected = Series(["foo", 2, 3], dtype=object, name="a")
@@ -1130,6 +1130,7 @@ def test_set_value_copy_only_necessary_column(
11301130
view = df[:]
11311131

11321132
if val == "a" and indexer[0] != slice(None):
1133+
# TODO(CoW-warn) assert the FutureWarning for CoW is also raised
11331134
with tm.assert_produces_warning(
11341135
FutureWarning, match="Setting an item of incompatible dtype is deprecated"
11351136
):
@@ -1154,6 +1155,8 @@ def test_series_midx_slice(using_copy_on_write):
11541155
ser = Series([1, 2, 3], index=pd.MultiIndex.from_arrays([[1, 1, 2], [3, 4, 5]]))
11551156
result = ser[1]
11561157
assert np.shares_memory(get_array(ser), get_array(result))
1158+
# TODO(CoW-warn) should warn -> reference is only tracked in CoW mode, so
1159+
# warning is not triggered
11571160
result.iloc[0] = 100
11581161
if using_copy_on_write:
11591162
expected = Series(
@@ -1162,7 +1165,9 @@ def test_series_midx_slice(using_copy_on_write):
11621165
tm.assert_series_equal(ser, expected)
11631166

11641167

1165-
def test_getitem_midx_slice(using_copy_on_write, using_array_manager):
1168+
def test_getitem_midx_slice(
1169+
using_copy_on_write, warn_copy_on_write, using_array_manager
1170+
):
11661171
df = DataFrame({("a", "x"): [1, 2], ("a", "y"): 1, ("b", "x"): 2})
11671172
df_orig = df.copy()
11681173
new_df = df[("a",)]
@@ -1175,6 +1180,15 @@ def test_getitem_midx_slice(using_copy_on_write, using_array_manager):
11751180
if using_copy_on_write:
11761181
new_df.iloc[0, 0] = 100
11771182
tm.assert_frame_equal(df_orig, df)
1183+
else:
1184+
if warn_copy_on_write:
1185+
with tm.assert_cow_warning():
1186+
new_df.iloc[0, 0] = 100
1187+
else:
1188+
with pd.option_context("chained_assignment", "warn"):
1189+
with tm.assert_produces_warning(SettingWithCopyWarning):
1190+
new_df.iloc[0, 0] = 100
1191+
assert df.iloc[0, 0] == 100
11781192

11791193

11801194
def test_series_midx_tuples_slice(using_copy_on_write):
@@ -1184,6 +1198,8 @@ def test_series_midx_tuples_slice(using_copy_on_write):
11841198
)
11851199
result = ser[(1, 2)]
11861200
assert np.shares_memory(get_array(ser), get_array(result))
1201+
# TODO(CoW-warn) should warn -> reference is only tracked in CoW mode, so
1202+
# warning is not triggered
11871203
result.iloc[0] = 100
11881204
if using_copy_on_write:
11891205
expected = Series(

pandas/tests/copy_view/test_setitem.py

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import numpy as np
2-
import pytest
32

43
from pandas import (
54
DataFrame,
@@ -67,8 +66,6 @@ def test_set_column_with_index(using_copy_on_write):
6766
assert not np.shares_memory(get_array(df, "d"), arr)
6867

6968

70-
# TODO(CoW-warn) this should NOT warn
71-
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
7269
def test_set_columns_with_dataframe(using_copy_on_write):
7370
# Case: setting a DataFrame as new columns copies that data
7471
# (with delayed copy with CoW)

pandas/tests/frame/indexing/test_indexing.py

-2
Original file line numberDiff line numberDiff line change
@@ -1466,8 +1466,6 @@ def test_loc_named_tuple_for_midx(self):
14661466
)
14671467
tm.assert_frame_equal(result, expected)
14681468

1469-
# TODO(CoW-warn) shouldn't warn, but does because of item cache
1470-
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
14711469
@pytest.mark.parametrize("indexer", [["a"], "a"])
14721470
@pytest.mark.parametrize("col", [{}, {"b": 1}])
14731471
def test_set_2d_casting_date_to_int(self, col, indexer):

pandas/tests/groupby/test_groupby.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_repr():
4141
assert result == expected
4242

4343

44-
# TODO(CoW-warn) this should NOT warn
44+
# TODO(CoW-warn) this should NOT warn -> inplace operator triggers it
4545
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
4646
def test_groupby_std_datetimelike(warn_copy_on_write):
4747
# GH#48481

pandas/tests/indexing/test_iloc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ def test_iloc_getitem_slice_dups(self):
424424
tm.assert_frame_equal(df.iloc[10:, :2], df2)
425425
tm.assert_frame_equal(df.iloc[10:, 2:], df1)
426426

427-
# TODO(CoW-warn) this should NOT warn
427+
# TODO(CoW-warn) this should NOT warn -> Series inplace operator
428428
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
429429
def test_iloc_setitem(self):
430430
df = DataFrame(

0 commit comments

Comments
 (0)