@@ -364,9 +364,12 @@ class Interval(_Constraint):
364
364
365
365
Parameters
366
366
----------
367
- type : {numbers.Integral, numbers.Real}
367
+ type : {numbers.Integral, numbers.Real, "real_not_int" }
368
368
The set of numbers in which to set the interval.
369
369
370
+ If "real_not_int", only reals that don't have the integer type
371
+ are allowed. For example 1.0 is allowed but 1 is not.
372
+
370
373
left : float or int or None
371
374
The left bound of the interval. None means left bound is -∞.
372
375
@@ -392,14 +395,6 @@ class Interval(_Constraint):
392
395
`[0, +∞) U {+∞}`.
393
396
"""
394
397
395
- @validate_params (
396
- {
397
- "type" : [type ],
398
- "left" : [Integral , Real , None ],
399
- "right" : [Integral , Real , None ],
400
- "closed" : [StrOptions ({"left" , "right" , "both" , "neither" })],
401
- }
402
- )
403
398
def __init__ (self , type , left , right , * , closed ):
404
399
super ().__init__ ()
405
400
self .type = type
@@ -410,6 +405,18 @@ def __init__(self, type, left, right, *, closed):
410
405
self ._check_params ()
411
406
412
407
def _check_params (self ):
408
+ if self .type not in (Integral , Real , "real_not_int" ):
409
+ raise ValueError (
410
+ "type must be either numbers.Integral, numbers.Real or 'real_not_int'."
411
+ f" Got { self .type } instead."
412
+ )
413
+
414
+ if self .closed not in ("left" , "right" , "both" , "neither" ):
415
+ raise ValueError (
416
+ "closed must be either 'left', 'right', 'both' or 'neither'. "
417
+ f"Got { self .closed } instead."
418
+ )
419
+
413
420
if self .type is Integral :
414
421
suffix = "for an interval over the integers."
415
422
if self .left is not None and not isinstance (self .left , Integral ):
@@ -424,6 +431,11 @@ def _check_params(self):
424
431
raise ValueError (
425
432
f"right can't be None when closed == { self .closed } { suffix } "
426
433
)
434
+ else :
435
+ if self .left is not None and not isinstance (self .left , Real ):
436
+ raise TypeError ("Expecting left to be a real number." )
437
+ if self .right is not None and not isinstance (self .right , Real ):
438
+ raise TypeError ("Expecting right to be a real number." )
427
439
428
440
if self .right is not None and self .left is not None and self .right <= self .left :
429
441
raise ValueError (
@@ -447,8 +459,13 @@ def __contains__(self, val):
447
459
return False
448
460
return True
449
461
462
+ def _has_valid_type (self , val ):
463
+ if self .type == "real_not_int" :
464
+ return isinstance (val , Real ) and not isinstance (val , Integral )
465
+ return isinstance (val , self .type )
466
+
450
467
def is_satisfied_by (self , val ):
451
- if not isinstance ( val , self .type ):
468
+ if not self ._has_valid_type ( val ):
452
469
return False
453
470
454
471
return val in self
0 commit comments