diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index dfdeba2a90554..046df233a5436 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -692,8 +692,8 @@ def __setitem__(self, key, value) -> None: if self._readonly: raise ValueError("Cannot modify read-only array") - value_left, value_right = self._validate_setitem_value(value) key = check_array_indexer(self, key) + value_left, value_right = self._validate_setitem_value(value) self._left[key] = value_left self._right[key] = value_right @@ -900,7 +900,7 @@ def fillna(self, value, limit: int | None = None, copy: bool = True) -> Self: if limit is not None: raise ValueError("limit must be None") - value_left, value_right = self._validate_scalar(value) + value_left, value_right = self._validate_setitem_value(value) left = self.left.fillna(value=value_left) right = self.right.fillna(value=value_right) @@ -1169,7 +1169,8 @@ def _validate_scalar(self, value): if isinstance(value, Interval): self._check_closed_matches(value, name="value") left, right = value.left, value.right - # TODO: check subdtype match like _validate_setitem_value? + self.left._validate_fill_value(left) + self.left._validate_fill_value(right) elif is_valid_na_for_dtype(value, self.left.dtype): # GH#18295 left = right = self.left._na_value @@ -1180,27 +1181,19 @@ def _validate_scalar(self, value): return left, right def _validate_setitem_value(self, value): + if is_list_like(value): + return self._validate_listlike(value) + + left, right = self._validate_scalar(value) + if is_valid_na_for_dtype(value, self.left.dtype): - # na value: need special casing to set directly on numpy arrays - value = self.left._na_value if is_integer_dtype(self.dtype.subtype): # can't set NaN on a numpy integer array # GH#45484 TypeError, not ValueError, matches what we get with # non-NA un-holdable value. raise TypeError("Cannot set float NaN to integer-backed IntervalArray") - value_left, value_right = value, value - - elif isinstance(value, Interval): - # scalar interval - self._check_closed_matches(value, name="value") - value_left, value_right = value.left, value.right - self.left._validate_fill_value(value_left) - self.left._validate_fill_value(value_right) - else: - return self._validate_listlike(value) - - return value_left, value_right + return left, right # --------------------------------------------------------------------- # Rendering Methods diff --git a/pandas/tests/arrays/interval/test_interval.py b/pandas/tests/arrays/interval/test_interval.py index 4b1f666c7e63b..cc37a9bc8793c 100644 --- a/pandas/tests/arrays/interval/test_interval.py +++ b/pandas/tests/arrays/interval/test_interval.py @@ -157,7 +157,7 @@ def test_set_na(self, left_right_dtypes): result = IntervalArray.from_arrays(left, right, copy=True) if result.dtype.subtype.kind not in ["m", "M"]: - msg = "'value' should be an interval type, got <.*NaTType'> instead." + msg = "can only insert Interval objects and NA into an IntervalArray" with pytest.raises(TypeError, match=msg): result[0] = pd.NaT if result.dtype.subtype.kind in ["i", "u"]: @@ -266,6 +266,6 @@ def test_min_max(self, left_right_dtypes, index_or_series_or_array): def test_fillna_non_scalar_raises(): arr = IntervalArray.from_tuples([None, (0, 1)]) - msg = "can only insert Interval objects and NA into an IntervalArray" + msg = "'value' should be an interval type, got instead." with pytest.raises(TypeError, match=msg): arr.fillna([1, 1])