diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index f91d40c4d9ea9..09353a0436697 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -958,7 +958,7 @@ Interval ^^^^^^^^ - :meth:`Index.is_monotonic_decreasing`, :meth:`Index.is_monotonic_increasing`, and :meth:`Index.is_unique` could incorrectly be ``False`` for an ``Index`` created from a slice of another ``Index``. (:issue:`57911`) - Bug in :func:`interval_range` where start and end numeric types were always cast to 64 bit (:issue:`57268`) -- +- Construction of :class:`IntervalArray` and :class:`IntervalIndex` from arrays with mismatched signed/unsigned integer dtypes (e.g., ``int64`` and ``uint64``) now raises a :exc:`TypeError` instead of proceeding silently. (:issue:`55715`) Indexing ^^^^^^^^ diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 8d13e76c57e4f..392a3a0c0b6c1 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -536,6 +536,19 @@ def from_arrays( left = _maybe_convert_platform_interval(left) right = _maybe_convert_platform_interval(right) + # Check for mismatched signed/unsigned integer dtypes + left_dtype = left.dtype + right_dtype = right.dtype + if ( + left_dtype.kind in "iu" + and right_dtype.kind in "iu" + and left_dtype.kind != right_dtype.kind + ): + raise TypeError( + f"Left and right arrays must have matching signedness. " + f"Got {left_dtype} and {right_dtype}." + ) + left, right, dtype = cls._ensure_simple_new_inputs( left, right, diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py index 006a06e529971..b302e865eebd1 100644 --- a/pandas/tests/indexes/interval/test_interval.py +++ b/pandas/tests/indexes/interval/test_interval.py @@ -882,6 +882,14 @@ def test_is_all_dates(self): assert not year_2017_index._is_all_dates +def test_from_arrays_mismatched_signedness_raises(): + # GH 55715 + left = np.array([0, 1, 2], dtype="int64") + right = np.array([1, 2, 3], dtype="uint64") + with pytest.raises(TypeError, match="matching signedness"): + IntervalIndex.from_arrays(left, right) + + def test_dir(): # GH#27571 dir(interval_index) should not raise index = IntervalIndex.from_arrays([0, 1], [1, 2])