@@ -419,7 +419,7 @@ def _from_factorized(cls, values, original):
419
419
# Validation Methods
420
420
# TODO: try to de-duplicate these, ensure identical behavior
421
421
422
- def _validate_comparison_value (self , other , opname : str ):
422
+ def _validate_comparison_value (self , other ):
423
423
if isinstance (other , str ):
424
424
try :
425
425
# GH#18435 strings get a pass from tzawareness compat
@@ -429,7 +429,7 @@ def _validate_comparison_value(self, other, opname: str):
429
429
raise InvalidComparison (other )
430
430
431
431
if isinstance (other , self ._recognized_scalars ) or other is NaT :
432
- other = self ._scalar_type (other ) # type: ignore[call-arg]
432
+ other = self ._scalar_type (other )
433
433
try :
434
434
self ._check_compatible_with (other )
435
435
except TypeError as err :
@@ -477,7 +477,7 @@ def _validate_fill_value(self, fill_value):
477
477
f"Got '{ str (fill_value )} '."
478
478
)
479
479
try :
480
- fill_value = self ._validate_scalar (fill_value , msg )
480
+ fill_value = self ._validate_scalar (fill_value )
481
481
except TypeError as err :
482
482
raise ValueError (msg ) from err
483
483
return self ._unbox (fill_value )
@@ -509,17 +509,16 @@ def _validate_shift_value(self, fill_value):
509
509
510
510
return self ._unbox (fill_value )
511
511
512
- def _validate_scalar (self , value , msg : Optional [ str ] = None ):
512
+ def _validate_scalar (self , value , allow_listlike : bool = False ):
513
513
"""
514
514
Validate that the input value can be cast to our scalar_type.
515
515
516
516
Parameters
517
517
----------
518
518
value : object
519
- msg : str, optional.
520
- Message to raise in TypeError on invalid input.
521
- If not provided, `value` is cast to a str and used
522
- as the message.
519
+ allow_listlike: bool, default False
520
+ When raising an exception, whether the message should say
521
+ listlike inputs are allowed.
523
522
524
523
Returns
525
524
-------
@@ -530,6 +529,7 @@ def _validate_scalar(self, value, msg: Optional[str] = None):
530
529
try :
531
530
value = self ._scalar_from_string (value )
532
531
except ValueError as err :
532
+ msg = self ._validation_error_message (value , allow_listlike )
533
533
raise TypeError (msg ) from err
534
534
535
535
elif is_valid_nat_for_dtype (value , self .dtype ):
@@ -541,12 +541,38 @@ def _validate_scalar(self, value, msg: Optional[str] = None):
541
541
value = self ._scalar_type (value ) # type: ignore[call-arg]
542
542
543
543
else :
544
- if msg is None :
545
- msg = str (value )
544
+ msg = self ._validation_error_message (value , allow_listlike )
546
545
raise TypeError (msg )
547
546
548
547
return value
549
548
549
+ def _validation_error_message (self , value , allow_listlike : bool = False ) -> str :
550
+ """
551
+ Construct an exception message on validation error.
552
+
553
+ Some methods allow only scalar inputs, while others allow either scalar
554
+ or listlike.
555
+
556
+ Parameters
557
+ ----------
558
+ allow_listlike: bool, default False
559
+
560
+ Returns
561
+ -------
562
+ str
563
+ """
564
+ if allow_listlike :
565
+ msg = (
566
+ f"value should be a '{ self ._scalar_type .__name__ } ', 'NaT', "
567
+ f"or array of those. Got '{ type (value ).__name__ } ' instead."
568
+ )
569
+ else :
570
+ msg = (
571
+ f"value should be a '{ self ._scalar_type .__name__ } ' or 'NaT'. "
572
+ f"Got '{ type (value ).__name__ } ' instead."
573
+ )
574
+ return msg
575
+
550
576
def _validate_listlike (self , value , allow_object : bool = False ):
551
577
if isinstance (value , type (self )):
552
578
return value
@@ -583,36 +609,29 @@ def _validate_listlike(self, value, allow_object: bool = False):
583
609
return value
584
610
585
611
def _validate_searchsorted_value (self , value ):
586
- msg = "searchsorted requires compatible dtype or scalar"
587
612
if not is_list_like (value ):
588
- value = self ._validate_scalar (value , msg )
613
+ value = self ._validate_scalar (value , True )
589
614
else :
590
615
value = self ._validate_listlike (value )
591
616
592
617
return self ._unbox (value )
593
618
594
619
def _validate_setitem_value (self , value ):
595
- msg = (
596
- f"'value' should be a '{ self ._scalar_type .__name__ } ', 'NaT', "
597
- f"or array of those. Got '{ type (value ).__name__ } ' instead."
598
- )
599
620
if is_list_like (value ):
600
621
value = self ._validate_listlike (value )
601
622
else :
602
- value = self ._validate_scalar (value , msg )
623
+ value = self ._validate_scalar (value , True )
603
624
604
625
return self ._unbox (value , setitem = True )
605
626
606
627
def _validate_insert_value (self , value ):
607
- msg = f"cannot insert { type (self ).__name__ } with incompatible label"
608
- value = self ._validate_scalar (value , msg )
628
+ value = self ._validate_scalar (value )
609
629
610
630
return self ._unbox (value , setitem = True )
611
631
612
632
def _validate_where_value (self , other ):
613
- msg = f"Where requires matching dtype, not { type (other )} "
614
633
if not is_list_like (other ):
615
- other = self ._validate_scalar (other , msg )
634
+ other = self ._validate_scalar (other , True )
616
635
else :
617
636
other = self ._validate_listlike (other )
618
637
@@ -844,7 +863,7 @@ def _cmp_method(self, other, op):
844
863
return op (self .ravel (), other .ravel ()).reshape (self .shape )
845
864
846
865
try :
847
- other = self ._validate_comparison_value (other , f"__ { op . __name__ } __" )
866
+ other = self ._validate_comparison_value (other )
848
867
except InvalidComparison :
849
868
return invalid_comparison (self , other , op )
850
869
0 commit comments