@@ -201,7 +201,7 @@ def test_setitem_chained_setfault(self, using_copy_on_write):
201
201
tm .assert_frame_equal (result , expected )
202
202
203
203
@pytest .mark .arm_slow
204
- def test_detect_chained_assignment (self , using_copy_on_write ):
204
+ def test_detect_chained_assignment (self , using_copy_on_write , warn_copy_on_write ):
205
205
with option_context ("chained_assignment" , "raise" ):
206
206
# work with the chain
207
207
expected = DataFrame ([[- 5 , 1 ], [- 6 , 3 ]], columns = list ("AB" ))
@@ -218,13 +218,16 @@ def test_detect_chained_assignment(self, using_copy_on_write):
218
218
df ["A" ][1 ] = - 6
219
219
tm .assert_frame_equal (df , df_original )
220
220
else :
221
- df ["A" ][0 ] = - 5
222
- df ["A" ][1 ] = - 6
221
+ warn = FutureWarning if warn_copy_on_write else None
222
+ with tm .assert_produces_warning (warn ):
223
+ df ["A" ][0 ] = - 5
224
+ with tm .assert_produces_warning (warn ):
225
+ df ["A" ][1 ] = - 6
223
226
tm .assert_frame_equal (df , expected )
224
227
225
228
@pytest .mark .arm_slow
226
229
def test_detect_chained_assignment_raises (
227
- self , using_array_manager , using_copy_on_write
230
+ self , using_array_manager , using_copy_on_write , warn_copy_on_write
228
231
):
229
232
# test with the chaining
230
233
df = DataFrame (
@@ -242,6 +245,11 @@ def test_detect_chained_assignment_raises(
242
245
with tm .raises_chained_assignment_error ():
243
246
df ["A" ][1 ] = - 6
244
247
tm .assert_frame_equal (df , df_original )
248
+ elif warn_copy_on_write :
249
+ with tm .assert_produces_warning (FutureWarning ):
250
+ df ["A" ][0 ] = - 5
251
+ with tm .assert_produces_warning (FutureWarning ):
252
+ df ["A" ][1 ] = np .nan
245
253
elif not using_array_manager :
246
254
with pytest .raises (SettingWithCopyError , match = msg ):
247
255
df ["A" ][0 ] = - 5
@@ -260,7 +268,9 @@ def test_detect_chained_assignment_raises(
260
268
tm .assert_frame_equal (df , expected )
261
269
262
270
@pytest .mark .arm_slow
263
- def test_detect_chained_assignment_fails (self , using_copy_on_write ):
271
+ def test_detect_chained_assignment_fails (
272
+ self , using_copy_on_write , warn_copy_on_write
273
+ ):
264
274
# Using a copy (the chain), fails
265
275
df = DataFrame (
266
276
{
@@ -272,12 +282,18 @@ def test_detect_chained_assignment_fails(self, using_copy_on_write):
272
282
if using_copy_on_write :
273
283
with tm .raises_chained_assignment_error ():
274
284
df .loc [0 ]["A" ] = - 5
285
+ elif warn_copy_on_write :
286
+ # TODO(CoW) should warn
287
+ with tm .assert_produces_warning (None ):
288
+ df .loc [0 ]["A" ] = - 5
275
289
else :
276
290
with pytest .raises (SettingWithCopyError , match = msg ):
277
291
df .loc [0 ]["A" ] = - 5
278
292
279
293
@pytest .mark .arm_slow
280
- def test_detect_chained_assignment_doc_example (self , using_copy_on_write ):
294
+ def test_detect_chained_assignment_doc_example (
295
+ self , using_copy_on_write , warn_copy_on_write
296
+ ):
281
297
# Doc example
282
298
df = DataFrame (
283
299
{
@@ -287,31 +303,39 @@ def test_detect_chained_assignment_doc_example(self, using_copy_on_write):
287
303
)
288
304
assert df ._is_copy is None
289
305
306
+ indexer = df .a .str .startswith ("o" )
290
307
if using_copy_on_write :
291
- indexer = df .a .str .startswith ("o" )
292
308
with tm .raises_chained_assignment_error ():
293
309
df [indexer ]["c" ] = 42
310
+ elif warn_copy_on_write :
311
+ # TODO(CoW) should warn
312
+ with tm .assert_produces_warning (None ):
313
+ df [indexer ]["c" ] = 42
294
314
else :
295
315
with pytest .raises (SettingWithCopyError , match = msg ):
296
- indexer = df .a .str .startswith ("o" )
297
316
df [indexer ]["c" ] = 42
298
317
299
318
@pytest .mark .arm_slow
300
319
def test_detect_chained_assignment_object_dtype (
301
- self , using_array_manager , using_copy_on_write
320
+ self , using_array_manager , using_copy_on_write , warn_copy_on_write
302
321
):
303
322
expected = DataFrame ({"A" : [111 , "bbb" , "ccc" ], "B" : [1 , 2 , 3 ]})
304
323
df = DataFrame ({"A" : ["aaa" , "bbb" , "ccc" ], "B" : [1 , 2 , 3 ]})
305
324
df_original = df .copy ()
306
325
307
- if not using_copy_on_write :
326
+ if not using_copy_on_write and not warn_copy_on_write :
308
327
with pytest .raises (SettingWithCopyError , match = msg ):
309
328
df .loc [0 ]["A" ] = 111
310
329
311
330
if using_copy_on_write :
312
331
with tm .raises_chained_assignment_error ():
313
332
df ["A" ][0 ] = 111
314
333
tm .assert_frame_equal (df , df_original )
334
+ elif warn_copy_on_write :
335
+ # TODO(CoW-warn) should give different message
336
+ with tm .assert_produces_warning (FutureWarning ):
337
+ df ["A" ][0 ] = 111
338
+ tm .assert_frame_equal (df , expected )
315
339
elif not using_array_manager :
316
340
with pytest .raises (SettingWithCopyError , match = msg ):
317
341
df ["A" ][0 ] = 111
@@ -367,8 +391,10 @@ def test_detect_chained_assignment_implicit_take(self):
367
391
df ["letters" ] = df ["letters" ].apply (str .lower )
368
392
369
393
@pytest .mark .arm_slow
370
- def test_detect_chained_assignment_implicit_take2 (self , using_copy_on_write ):
371
- if using_copy_on_write :
394
+ def test_detect_chained_assignment_implicit_take2 (
395
+ self , using_copy_on_write , warn_copy_on_write
396
+ ):
397
+ if using_copy_on_write or warn_copy_on_write :
372
398
pytest .skip ("_is_copy is not always set for CoW" )
373
399
# Implicitly take 2
374
400
df = random_text (100000 )
@@ -422,7 +448,9 @@ def test_detect_chained_assignment_false_positives(self):
422
448
str (df )
423
449
424
450
@pytest .mark .arm_slow
425
- def test_detect_chained_assignment_undefined_column (self , using_copy_on_write ):
451
+ def test_detect_chained_assignment_undefined_column (
452
+ self , using_copy_on_write , warn_copy_on_write
453
+ ):
426
454
# from SO:
427
455
# https://stackoverflow.com/questions/24054495/potential-bug-setting-value-for-undefined-column-using-iloc
428
456
df = DataFrame (np .arange (0 , 9 ), columns = ["count" ])
@@ -433,13 +461,17 @@ def test_detect_chained_assignment_undefined_column(self, using_copy_on_write):
433
461
with tm .raises_chained_assignment_error ():
434
462
df .iloc [0 :5 ]["group" ] = "a"
435
463
tm .assert_frame_equal (df , df_original )
464
+ elif warn_copy_on_write :
465
+ # TODO(CoW-warn) should warn
466
+ with tm .assert_produces_warning (None ):
467
+ df .iloc [0 :5 ]["group" ] = "a"
436
468
else :
437
469
with pytest .raises (SettingWithCopyError , match = msg ):
438
470
df .iloc [0 :5 ]["group" ] = "a"
439
471
440
472
@pytest .mark .arm_slow
441
473
def test_detect_chained_assignment_changing_dtype (
442
- self , using_array_manager , using_copy_on_write
474
+ self , using_array_manager , using_copy_on_write , warn_copy_on_write
443
475
):
444
476
# Mixed type setting but same dtype & changing dtype
445
477
df = DataFrame (
@@ -460,8 +492,14 @@ def test_detect_chained_assignment_changing_dtype(
460
492
with tm .raises_chained_assignment_error (extra_warnings = (FutureWarning ,)):
461
493
df ["C" ][2 ] = "foo"
462
494
tm .assert_frame_equal (df , df_original )
463
-
464
- if not using_copy_on_write :
495
+ elif warn_copy_on_write :
496
+ # TODO(CoW-warn) should warn
497
+ with tm .assert_produces_warning (None ):
498
+ df .loc [2 ]["D" ] = "foo"
499
+ # TODO(CoW-warn) should give different message
500
+ with tm .assert_produces_warning (FutureWarning ):
501
+ df ["C" ][2 ] = "foo"
502
+ else :
465
503
with pytest .raises (SettingWithCopyError , match = msg ):
466
504
df .loc [2 ]["D" ] = "foo"
467
505
@@ -477,7 +515,7 @@ def test_detect_chained_assignment_changing_dtype(
477
515
df ["C" ][2 ] = "foo"
478
516
assert df .loc [2 , "C" ] == "foo"
479
517
480
- def test_setting_with_copy_bug (self , using_copy_on_write ):
518
+ def test_setting_with_copy_bug (self , using_copy_on_write , warn_copy_on_write ):
481
519
# operating on a copy
482
520
df = DataFrame (
483
521
{"a" : list (range (4 )), "b" : list ("ab.." ), "c" : ["a" , "b" , np .nan , "d" ]}
@@ -489,6 +527,10 @@ def test_setting_with_copy_bug(self, using_copy_on_write):
489
527
with tm .raises_chained_assignment_error ():
490
528
df [["c" ]][mask ] = df [["b" ]][mask ]
491
529
tm .assert_frame_equal (df , df_original )
530
+ elif warn_copy_on_write :
531
+ # TODO(CoW-warn) should warn
532
+ with tm .assert_produces_warning (None ):
533
+ df [["c" ]][mask ] = df [["b" ]][mask ]
492
534
else :
493
535
with pytest .raises (SettingWithCopyError , match = msg ):
494
536
df [["c" ]][mask ] = df [["b" ]][mask ]
@@ -502,12 +544,19 @@ def test_setting_with_copy_bug_no_warning(self):
502
544
# this should not raise
503
545
df2 ["y" ] = ["g" , "h" , "i" ]
504
546
505
- def test_detect_chained_assignment_warnings_errors (self , using_copy_on_write ):
547
+ def test_detect_chained_assignment_warnings_errors (
548
+ self , using_copy_on_write , warn_copy_on_write
549
+ ):
506
550
df = DataFrame ({"A" : ["aaa" , "bbb" , "ccc" ], "B" : [1 , 2 , 3 ]})
507
551
if using_copy_on_write :
508
552
with tm .raises_chained_assignment_error ():
509
553
df .loc [0 ]["A" ] = 111
510
554
return
555
+ elif warn_copy_on_write :
556
+ # TODO(CoW-warn) should warn
557
+ with tm .assert_produces_warning (None ):
558
+ df .loc [0 ]["A" ] = 111
559
+ return
511
560
512
561
with option_context ("chained_assignment" , "warn" ):
513
562
with tm .assert_produces_warning (SettingWithCopyWarning ):
@@ -519,14 +568,14 @@ def test_detect_chained_assignment_warnings_errors(self, using_copy_on_write):
519
568
520
569
@pytest .mark .parametrize ("rhs" , [3 , DataFrame ({0 : [1 , 2 , 3 , 4 ]})])
521
570
def test_detect_chained_assignment_warning_stacklevel (
522
- self , rhs , using_copy_on_write
571
+ self , rhs , using_copy_on_write , warn_copy_on_write
523
572
):
524
573
# GH#42570
525
574
df = DataFrame (np .arange (25 ).reshape (5 , 5 ))
526
575
df_original = df .copy ()
527
576
chained = df .loc [:3 ]
528
577
with option_context ("chained_assignment" , "warn" ):
529
- if not using_copy_on_write :
578
+ if not using_copy_on_write and not warn_copy_on_write :
530
579
with tm .assert_produces_warning (SettingWithCopyWarning ) as t :
531
580
chained [2 ] = rhs
532
581
assert t [0 ].filename == __file__
0 commit comments