@@ -307,57 +307,71 @@ class SetitemCastingEquivalents:
307307 - the setitem does not expand the obj
308308 """
309309
310- @pytest .fixture ( params = [ np . nan , np . float64 ( "NaN" )])
311- def val (self , request ):
310+ @pytest .fixture
311+ def is_inplace (self ):
312312 """
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.
315314 """
316- return request . param
315+ return None
317316
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
319319 obj = obj .copy ()
320+ arr = obj ._values
321+
320322 indexer (obj )[key ] = val
321323 tm .assert_series_equal (obj , expected )
322324
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 ):
324338 if not isinstance (key , int ):
325339 return
326340
327- self .check_indexer (obj , key , expected , val , indexer_sli )
341+ self .check_indexer (obj , key , expected , val , indexer_sli , is_inplace )
328342
329343 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 )
331345 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 )
333347
334348 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 )
336350
337351 if indexer_sli is not tm .loc :
338352 # Note: no .loc because that handles slice edges differently
339353 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 )
341355
342356 ilkey = [key ]
343- self .check_indexer (obj , ilkey , expected , val , indexer_sli )
357+ self .check_indexer (obj , ilkey , expected , val , indexer_sli , is_inplace )
344358
345359 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 )
347361
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 ):
349363 if not isinstance (key , slice ):
350364 return
351365
352366 if indexer_sli is not tm .loc :
353367 # 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 )
355369
356370 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 )
358372
359373 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 )
361375
362376 def test_mask_key (self , obj , key , expected , val , indexer_sli ):
363377 # setitem with boolean mask
@@ -368,14 +382,19 @@ def test_mask_key(self, obj, key, expected, val, indexer_sli):
368382 indexer_sli (obj )[mask ] = val
369383 tm .assert_series_equal (obj , expected )
370384
371- def test_series_where (self , obj , key , expected , val ):
385+ def test_series_where (self , obj , key , expected , val , is_inplace ):
372386 mask = np .zeros (obj .shape , dtype = bool )
373387 mask [key ] = True
374388
389+ orig = obj
375390 obj = obj .copy ()
391+ arr = obj ._values
392+
376393 res = obj .where (~ mask , val )
377394 tm .assert_series_equal (res , expected )
378395
396+ self ._check_inplace (is_inplace , orig , arr , obj )
397+
379398 def test_index_where (self , obj , key , expected , val , request ):
380399 if Index (obj ).dtype != obj .dtype :
381400 pytest .skip ("test not applicable for this dtype" )
@@ -519,15 +538,15 @@ def test_setitem_slice_into_readonly_backing_data():
519538 assert not array .any ()
520539
521540
522- class TestSetitemCastingEquivalentsTimedelta64IntoNumeric :
541+ class TestSetitemTimedelta64IntoNumeric ( SetitemCastingEquivalents ) :
523542 # timedelta64 should not be treated as integers when setting into
524543 # numeric Series
525544
526545 @pytest .fixture
527546 def val (self ):
528547 td = np .timedelta64 (4 , "ns" )
529548 return td
530- return np .full ((1 ,), td )
549+ # TODO: could also try np.full((1,), td)
531550
532551 @pytest .fixture (params = [complex , int , float ])
533552 def dtype (self , request ):
@@ -551,91 +570,9 @@ def expected(self, dtype):
551570 def key (self ):
552571 return 0
553572
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