@@ -547,38 +547,7 @@ def __getitem__(self, value):
547
547
return self ._shallow_copy (left , right )
548
548
549
549
def __setitem__ (self , key , value ):
550
- # na value: need special casing to set directly on numpy arrays
551
- needs_float_conversion = False
552
- if is_scalar (value ) and isna (value ):
553
- if is_integer_dtype (self .dtype .subtype ):
554
- # can't set NaN on a numpy integer array
555
- needs_float_conversion = True
556
- elif is_datetime64_any_dtype (self .dtype .subtype ):
557
- # need proper NaT to set directly on the numpy array
558
- value = np .datetime64 ("NaT" )
559
- elif is_timedelta64_dtype (self .dtype .subtype ):
560
- # need proper NaT to set directly on the numpy array
561
- value = np .timedelta64 ("NaT" )
562
- value_left , value_right = value , value
563
-
564
- # scalar interval
565
- elif is_interval_dtype (value ) or isinstance (value , Interval ):
566
- self ._check_closed_matches (value , name = "value" )
567
- value_left , value_right = value .left , value .right
568
-
569
- else :
570
- # list-like of intervals
571
- try :
572
- array = IntervalArray (value )
573
- value_left , value_right = array .left , array .right
574
- except TypeError as err :
575
- # wrong type: not interval or NA
576
- msg = f"'value' should be an interval type, got { type (value )} instead."
577
- raise TypeError (msg ) from err
578
-
579
- if needs_float_conversion :
580
- raise ValueError ("Cannot set float NaN to integer-backed IntervalArray" )
581
-
550
+ value_left , value_right = self ._validate_setitem_value (value )
582
551
key = check_array_indexer (self , key )
583
552
584
553
# Need to ensure that left and right are updated atomically, so we're
@@ -898,6 +867,41 @@ def _validate_insert_value(self, value):
898
867
)
899
868
return left_insert , right_insert
900
869
870
+ def _validate_setitem_value (self , value ):
871
+ needs_float_conversion = False
872
+
873
+ if is_scalar (value ) and isna (value ):
874
+ # na value: need special casing to set directly on numpy arrays
875
+ if is_integer_dtype (self .dtype .subtype ):
876
+ # can't set NaN on a numpy integer array
877
+ needs_float_conversion = True
878
+ elif is_datetime64_any_dtype (self .dtype .subtype ):
879
+ # need proper NaT to set directly on the numpy array
880
+ value = np .datetime64 ("NaT" )
881
+ elif is_timedelta64_dtype (self .dtype .subtype ):
882
+ # need proper NaT to set directly on the numpy array
883
+ value = np .timedelta64 ("NaT" )
884
+ value_left , value_right = value , value
885
+
886
+ elif is_interval_dtype (value ) or isinstance (value , Interval ):
887
+ # scalar interval
888
+ self ._check_closed_matches (value , name = "value" )
889
+ value_left , value_right = value .left , value .right
890
+
891
+ else :
892
+ try :
893
+ # list-like of intervals
894
+ array = IntervalArray (value )
895
+ value_left , value_right = array .left , array .right
896
+ except TypeError as err :
897
+ # wrong type: not interval or NA
898
+ msg = f"'value' should be an interval type, got { type (value )} instead."
899
+ raise TypeError (msg ) from err
900
+
901
+ if needs_float_conversion :
902
+ raise ValueError ("Cannot set float NaN to integer-backed IntervalArray" )
903
+ return value_left , value_right
904
+
901
905
def value_counts (self , dropna = True ):
902
906
"""
903
907
Returns a Series containing counts of each interval.
0 commit comments