@@ -307,57 +307,71 @@ class SetitemCastingEquivalents:
307
307
- the setitem does not expand the obj
308
308
"""
309
309
310
- @pytest .fixture ( params = [ np . nan , np . float64 ( "NaN" )])
311
- def val (self , request ):
310
+ @pytest .fixture
311
+ def is_inplace (self ):
312
312
"""
313
- One python float NaN, one np.float64. Only np.float64 has a `dtype`
314
- attribute.
313
+ Indicate that we are not (yet) checking whether or not setting is inplace.
315
314
"""
316
- return request . param
315
+ return None
317
316
318
- def check_indexer (self , obj , key , expected , val , indexer ):
317
+ def check_indexer (self , obj , key , expected , val , indexer , is_inplace ):
318
+ orig = obj
319
319
obj = obj .copy ()
320
+ arr = obj ._values
321
+
320
322
indexer (obj )[key ] = val
321
323
tm .assert_series_equal (obj , expected )
322
324
323
- def test_int_key (self , obj , key , expected , val , indexer_sli ):
325
+ self ._check_inplace (is_inplace , orig , arr , obj )
326
+
327
+ def _check_inplace (self , is_inplace , orig , arr , obj ):
328
+ if is_inplace is None :
329
+ # We are not (yet) checking whether setting is inplace or not
330
+ pass
331
+ elif is_inplace :
332
+ assert obj ._values is arr
333
+ else :
334
+ # otherwise original array should be unchanged
335
+ tm .assert_equal (arr , orig ._values )
336
+
337
+ def test_int_key (self , obj , key , expected , val , indexer_sli , is_inplace ):
324
338
if not isinstance (key , int ):
325
339
return
326
340
327
- self .check_indexer (obj , key , expected , val , indexer_sli )
341
+ self .check_indexer (obj , key , expected , val , indexer_sli , is_inplace )
328
342
329
343
if indexer_sli is tm .loc :
330
- self .check_indexer (obj , key , expected , val , tm .at )
344
+ self .check_indexer (obj , key , expected , val , tm .at , is_inplace )
331
345
elif indexer_sli is tm .iloc :
332
- self .check_indexer (obj , key , expected , val , tm .iat )
346
+ self .check_indexer (obj , key , expected , val , tm .iat , is_inplace )
333
347
334
348
rng = range (key , key + 1 )
335
- self .check_indexer (obj , rng , expected , val , indexer_sli )
349
+ self .check_indexer (obj , rng , expected , val , indexer_sli , is_inplace )
336
350
337
351
if indexer_sli is not tm .loc :
338
352
# Note: no .loc because that handles slice edges differently
339
353
slc = slice (key , key + 1 )
340
- self .check_indexer (obj , slc , expected , val , indexer_sli )
354
+ self .check_indexer (obj , slc , expected , val , indexer_sli , is_inplace )
341
355
342
356
ilkey = [key ]
343
- self .check_indexer (obj , ilkey , expected , val , indexer_sli )
357
+ self .check_indexer (obj , ilkey , expected , val , indexer_sli , is_inplace )
344
358
345
359
indkey = np .array (ilkey )
346
- self .check_indexer (obj , indkey , expected , val , indexer_sli )
360
+ self .check_indexer (obj , indkey , expected , val , indexer_sli , is_inplace )
347
361
348
- def test_slice_key (self , obj , key , expected , val , indexer_sli ):
362
+ def test_slice_key (self , obj , key , expected , val , indexer_sli , is_inplace ):
349
363
if not isinstance (key , slice ):
350
364
return
351
365
352
366
if indexer_sli is not tm .loc :
353
367
# Note: no .loc because that handles slice edges differently
354
- self .check_indexer (obj , key , expected , val , indexer_sli )
368
+ self .check_indexer (obj , key , expected , val , indexer_sli , is_inplace )
355
369
356
370
ilkey = list (range (len (obj )))[key ]
357
- self .check_indexer (obj , ilkey , expected , val , indexer_sli )
371
+ self .check_indexer (obj , ilkey , expected , val , indexer_sli , is_inplace )
358
372
359
373
indkey = np .array (ilkey )
360
- self .check_indexer (obj , indkey , expected , val , indexer_sli )
374
+ self .check_indexer (obj , indkey , expected , val , indexer_sli , is_inplace )
361
375
362
376
def test_mask_key (self , obj , key , expected , val , indexer_sli ):
363
377
# setitem with boolean mask
@@ -368,14 +382,19 @@ def test_mask_key(self, obj, key, expected, val, indexer_sli):
368
382
indexer_sli (obj )[mask ] = val
369
383
tm .assert_series_equal (obj , expected )
370
384
371
- def test_series_where (self , obj , key , expected , val ):
385
+ def test_series_where (self , obj , key , expected , val , is_inplace ):
372
386
mask = np .zeros (obj .shape , dtype = bool )
373
387
mask [key ] = True
374
388
389
+ orig = obj
375
390
obj = obj .copy ()
391
+ arr = obj ._values
392
+
376
393
res = obj .where (~ mask , val )
377
394
tm .assert_series_equal (res , expected )
378
395
396
+ self ._check_inplace (is_inplace , orig , arr , obj )
397
+
379
398
def test_index_where (self , obj , key , expected , val , request ):
380
399
if Index (obj ).dtype != obj .dtype :
381
400
pytest .skip ("test not applicable for this dtype" )
@@ -519,15 +538,15 @@ def test_setitem_slice_into_readonly_backing_data():
519
538
assert not array .any ()
520
539
521
540
522
- class TestSetitemCastingEquivalentsTimedelta64IntoNumeric :
541
+ class TestSetitemTimedelta64IntoNumeric ( SetitemCastingEquivalents ) :
523
542
# timedelta64 should not be treated as integers when setting into
524
543
# numeric Series
525
544
526
545
@pytest .fixture
527
546
def val (self ):
528
547
td = np .timedelta64 (4 , "ns" )
529
548
return td
530
- return np .full ((1 ,), td )
549
+ # TODO: could also try np.full((1,), td)
531
550
532
551
@pytest .fixture (params = [complex , int , float ])
533
552
def dtype (self , request ):
@@ -551,91 +570,9 @@ def expected(self, dtype):
551
570
def key (self ):
552
571
return 0
553
572
554
- def check_indexer (self , obj , key , expected , val , indexer ):
555
- orig = obj
556
- obj = obj .copy ()
557
- arr = obj ._values
558
-
559
- indexer (obj )[key ] = val
560
- tm .assert_series_equal (obj , expected )
561
-
562
- tm .assert_equal (arr , orig ._values ) # original array is unchanged
563
-
564
- def test_int_key (self , obj , key , expected , val , indexer_sli ):
565
- if not isinstance (key , int ):
566
- return
567
-
568
- self .check_indexer (obj , key , expected , val , indexer_sli )
569
-
570
- rng = range (key , key + 1 )
571
- self .check_indexer (obj , rng , expected , val , indexer_sli )
572
-
573
- if indexer_sli is not tm .loc :
574
- # Note: no .loc because that handles slice edges differently
575
- slc = slice (key , key + 1 )
576
- self .check_indexer (obj , slc , expected , val , indexer_sli )
577
-
578
- ilkey = [key ]
579
- self .check_indexer (obj , ilkey , expected , val , indexer_sli )
580
-
581
- indkey = np .array (ilkey )
582
- self .check_indexer (obj , indkey , expected , val , indexer_sli )
583
-
584
- def test_slice_key (self , obj , key , expected , val , indexer_sli ):
585
- if not isinstance (key , slice ):
586
- return
587
-
588
- if indexer_sli is not tm .loc :
589
- # Note: no .loc because that handles slice edges differently
590
- self .check_indexer (obj , key , expected , val , indexer_sli )
591
-
592
- ilkey = list (range (len (obj )))[key ]
593
- self .check_indexer (obj , ilkey , expected , val , indexer_sli )
594
-
595
- indkey = np .array (ilkey )
596
- self .check_indexer (obj , indkey , expected , val , indexer_sli )
597
-
598
- def test_mask_key (self , obj , key , expected , val , indexer_sli ):
599
- # setitem with boolean mask
600
- mask = np .zeros (obj .shape , dtype = bool )
601
- mask [key ] = True
602
-
603
- self .check_indexer (obj , mask , expected , val , indexer_sli )
604
-
605
- def test_series_where (self , obj , key , expected , val ):
606
- mask = np .zeros (obj .shape , dtype = bool )
607
- mask [key ] = True
608
-
609
- orig = obj
610
- obj = obj .copy ()
611
- arr = obj ._values
612
- res = obj .where (~ mask , val )
613
- tm .assert_series_equal (res , expected )
614
-
615
- tm .assert_equal (arr , orig ._values ) # original array is unchanged
616
-
617
- def test_index_where (self , obj , key , expected , val , request ):
618
- if Index (obj ).dtype != obj .dtype :
619
- pytest .skip ("test not applicable for this dtype" )
620
-
621
- mask = np .zeros (obj .shape , dtype = bool )
622
- mask [key ] = True
623
-
624
- if obj .dtype == bool and not mask .all ():
625
- # When mask is all True, casting behavior does not apply
626
- msg = "Index/Series casting behavior inconsistent GH#38692"
627
- mark = pytest .mark .xfail (reason = msg )
628
- request .node .add_marker (mark )
629
-
630
- res = Index (obj ).where (~ mask , val )
631
- tm .assert_index_equal (res , Index (expected ))
632
-
633
- def test_index_putmask (self , obj , key , expected , val ):
634
- if Index (obj ).dtype != obj .dtype :
635
- pytest .skip ("test not applicable for this dtype" )
636
-
637
- mask = np .zeros (obj .shape , dtype = bool )
638
- mask [key ] = True
639
-
640
- res = Index (obj ).putmask (mask , val )
641
- tm .assert_index_equal (res , Index (expected ))
573
+ @pytest .fixture
574
+ def is_inplace (self ):
575
+ """
576
+ Indicate we do _not_ expect the setting to be done inplace.
577
+ """
578
+ return False
0 commit comments