@@ -232,9 +232,10 @@ def __new__(
232
232
data = extract_array (data , extract_numpy = True )
233
233
234
234
if isinstance (data , cls ):
235
- left = data ._left
236
- right = data ._right
235
+ left : ArrayLike = data ._left
236
+ right : ArrayLike = data ._right
237
237
closed = closed or data .closed
238
+ dtype = IntervalDtype (left .dtype , closed = closed )
238
239
else :
239
240
240
241
# don't allow scalars
@@ -255,11 +256,13 @@ def __new__(
255
256
right = lib .maybe_convert_objects (right )
256
257
closed = closed or infer_closed
257
258
259
+ left , right , dtype = cls ._ensure_simple_new_inputs (
260
+ left , right , closed = closed , copy = copy , dtype = dtype
261
+ )
262
+
258
263
return cls ._simple_new (
259
264
left ,
260
265
right ,
261
- closed ,
262
- copy = copy ,
263
266
dtype = dtype ,
264
267
verify_integrity = verify_integrity ,
265
268
)
@@ -269,23 +272,39 @@ def _simple_new(
269
272
cls : type [IntervalArrayT ],
270
273
left ,
271
274
right ,
272
- closed : IntervalClosedType | None = None ,
273
- copy : bool = False ,
274
- dtype : Dtype | None = None ,
275
+ dtype : IntervalDtype ,
275
276
verify_integrity : bool = True ,
276
277
) -> IntervalArrayT :
277
278
result = IntervalMixin .__new__ (cls )
279
+ result ._left = left
280
+ result ._right = right
281
+ result ._dtype = dtype
278
282
279
- if closed is None and isinstance ( dtype , IntervalDtype ) :
280
- closed = dtype . closed
283
+ if verify_integrity :
284
+ result . _validate ()
281
285
282
- closed = closed or "right"
286
+ return result
283
287
288
+ @classmethod
289
+ def _ensure_simple_new_inputs (
290
+ cls ,
291
+ left ,
292
+ right ,
293
+ closed : IntervalClosedType | None = None ,
294
+ copy : bool = False ,
295
+ dtype : Dtype | None = None ,
296
+ ) -> tuple [ArrayLike , ArrayLike , IntervalDtype ]:
297
+ """Ensure correctness of input parameters for cls._simple_new."""
284
298
from pandas .core .indexes .base import ensure_index
285
299
286
300
left = ensure_index (left , copy = copy )
287
301
right = ensure_index (right , copy = copy )
288
302
303
+ if closed is None and isinstance (dtype , IntervalDtype ):
304
+ closed = dtype .closed
305
+
306
+ closed = closed or "right"
307
+
289
308
if dtype is not None :
290
309
# GH 19262: dtype must be an IntervalDtype to override inferred
291
310
dtype = pandas_dtype (dtype )
@@ -346,13 +365,8 @@ def _simple_new(
346
365
right = right .copy ()
347
366
348
367
dtype = IntervalDtype (left .dtype , closed = closed )
349
- result ._dtype = dtype
350
368
351
- result ._left = left
352
- result ._right = right
353
- if verify_integrity :
354
- result ._validate ()
355
- return result
369
+ return left , right , dtype
356
370
357
371
@classmethod
358
372
def _from_sequence (
@@ -512,10 +526,12 @@ def from_arrays(
512
526
left = _maybe_convert_platform_interval (left )
513
527
right = _maybe_convert_platform_interval (right )
514
528
515
- return cls ._simple_new (
516
- left , right , closed , copy = copy , dtype = dtype , verify_integrity = True
529
+ left , right , dtype = cls ._ensure_simple_new_inputs (
530
+ left , right , closed = closed , copy = copy , dtype = dtype
517
531
)
518
532
533
+ return cls ._simple_new (left , right , dtype = dtype , verify_integrity = True )
534
+
519
535
_interval_shared_docs ["from_tuples" ] = textwrap .dedent (
520
536
"""
521
537
Construct an %(klass)s from an array-like of tuples.
@@ -639,7 +655,9 @@ def _shallow_copy(self: IntervalArrayT, left, right) -> IntervalArrayT:
639
655
right : Index
640
656
Values to be used for the right-side of the intervals.
641
657
"""
642
- return self ._simple_new (left , right , closed = self .closed , verify_integrity = False )
658
+ dtype = IntervalDtype (left .dtype , closed = self .closed )
659
+ left , right , dtype = self ._ensure_simple_new_inputs (left , right , dtype = dtype )
660
+ return self ._simple_new (left , right , dtype = dtype , verify_integrity = False )
643
661
644
662
# ---------------------------------------------------------------------
645
663
# Descriptive
@@ -986,7 +1004,10 @@ def _concat_same_type(
986
1004
987
1005
left = np .concatenate ([interval .left for interval in to_concat ])
988
1006
right = np .concatenate ([interval .right for interval in to_concat ])
989
- return cls ._simple_new (left , right , closed = closed , copy = False )
1007
+
1008
+ left , right , dtype = cls ._ensure_simple_new_inputs (left , right , closed = closed )
1009
+
1010
+ return cls ._simple_new (left , right , dtype = dtype )
990
1011
991
1012
def copy (self : IntervalArrayT ) -> IntervalArrayT :
992
1013
"""
@@ -1400,9 +1421,9 @@ def set_closed(self: IntervalArrayT, closed: IntervalClosedType) -> IntervalArra
1400
1421
msg = f"invalid option for 'closed': { closed } "
1401
1422
raise ValueError (msg )
1402
1423
1403
- return type ( self ). _simple_new (
1404
- left = self . _left , right = self . _right , closed = closed , verify_integrity = False
1405
- )
1424
+ left , right = self . _left , self . _right
1425
+ dtype = IntervalDtype ( left . dtype , closed = closed )
1426
+ return self . _simple_new ( left , right , dtype = dtype , verify_integrity = False )
1406
1427
1407
1428
_interval_shared_docs [
1408
1429
"is_non_overlapping_monotonic"
0 commit comments