Skip to content

Commit 8b05fe3

Browse files
authored
REF: de-duplicate _validate_insert_value with _validate_scalar (pandas-dev#37640)
1 parent d5f6dd9 commit 8b05fe3

File tree

10 files changed

+35
-25
lines changed

10 files changed

+35
-25
lines changed

pandas/core/arrays/_mixins.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def _box_func(self, x):
4545
"""
4646
return x
4747

48-
def _validate_insert_value(self, value):
48+
def _validate_scalar(self, value):
4949
# used by NDArrayBackedExtensionIndex.insert
5050
raise AbstractMethodError(self)
5151

pandas/core/arrays/categorical.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1177,9 +1177,6 @@ def map(self, mapper):
11771177
# -------------------------------------------------------------
11781178
# Validators; ideally these can be de-duplicated
11791179

1180-
def _validate_insert_value(self, value) -> int:
1181-
return self._validate_fill_value(value)
1182-
11831180
def _validate_searchsorted_value(self, value):
11841181
# searchsorted is very performance sensitive. By converting codes
11851182
# to same dtype as self.codes, we get much faster performance.
@@ -1219,6 +1216,8 @@ def _validate_fill_value(self, fill_value):
12191216
)
12201217
return fill_value
12211218

1219+
_validate_scalar = _validate_fill_value
1220+
12221221
# -------------------------------------------------------------
12231222

12241223
def __array__(self, dtype=None) -> np.ndarray:

pandas/core/arrays/datetimelike.py

+25-11
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,12 @@ def _validate_fill_value(self, fill_value):
479479
f"Got '{str(fill_value)}'."
480480
)
481481
try:
482-
fill_value = self._validate_scalar(fill_value)
482+
return self._validate_scalar(fill_value)
483483
except TypeError as err:
484+
if "Cannot compare tz-naive and tz-aware" in str(err):
485+
# tzawareness-compat
486+
raise
484487
raise ValueError(msg) from err
485-
return self._unbox(fill_value, setitem=True)
486488

487489
def _validate_shift_value(self, fill_value):
488490
# TODO(2.0): once this deprecation is enforced, use _validate_fill_value
@@ -511,7 +513,14 @@ def _validate_shift_value(self, fill_value):
511513

512514
return self._unbox(fill_value, setitem=True)
513515

514-
def _validate_scalar(self, value, allow_listlike: bool = False):
516+
def _validate_scalar(
517+
self,
518+
value,
519+
*,
520+
allow_listlike: bool = False,
521+
setitem: bool = True,
522+
unbox: bool = True,
523+
):
515524
"""
516525
Validate that the input value can be cast to our scalar_type.
517526
@@ -521,6 +530,11 @@ def _validate_scalar(self, value, allow_listlike: bool = False):
521530
allow_listlike: bool, default False
522531
When raising an exception, whether the message should say
523532
listlike inputs are allowed.
533+
setitem : bool, default True
534+
Whether to check compatibility with setitem strictness.
535+
unbox : bool, default True
536+
Whether to unbox the result before returning. Note: unbox=False
537+
skips the setitem compatibility check.
524538
525539
Returns
526540
-------
@@ -546,7 +560,12 @@ def _validate_scalar(self, value, allow_listlike: bool = False):
546560
msg = self._validation_error_message(value, allow_listlike)
547561
raise TypeError(msg)
548562

549-
return value
563+
if not unbox:
564+
# NB: In general NDArrayBackedExtensionArray will unbox here;
565+
# this option exists to prevent a performance hit in
566+
# TimedeltaIndex.get_loc
567+
return value
568+
return self._unbox_scalar(value, setitem=setitem)
550569

551570
def _validation_error_message(self, value, allow_listlike: bool = False) -> str:
552571
"""
@@ -611,7 +630,7 @@ def _validate_listlike(self, value, allow_object: bool = False):
611630

612631
def _validate_searchsorted_value(self, value):
613632
if not is_list_like(value):
614-
value = self._validate_scalar(value, True)
633+
return self._validate_scalar(value, allow_listlike=True, setitem=False)
615634
else:
616635
value = self._validate_listlike(value)
617636

@@ -621,12 +640,7 @@ def _validate_setitem_value(self, value):
621640
if is_list_like(value):
622641
value = self._validate_listlike(value)
623642
else:
624-
value = self._validate_scalar(value, True)
625-
626-
return self._unbox(value, setitem=True)
627-
628-
def _validate_insert_value(self, value):
629-
value = self._validate_scalar(value)
643+
return self._validate_scalar(value, allow_listlike=True)
630644

631645
return self._unbox(value, setitem=True)
632646

pandas/core/arrays/interval.py

-3
Original file line numberDiff line numberDiff line change
@@ -889,9 +889,6 @@ def _validate_fillna_value(self, value):
889889
)
890890
raise TypeError(msg) from err
891891

892-
def _validate_insert_value(self, value):
893-
return self._validate_scalar(value)
894-
895892
def _validate_setitem_value(self, value):
896893
needs_float_conversion = False
897894

pandas/core/indexes/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2292,7 +2292,7 @@ def fillna(self, value=None, downcast=None):
22922292
DataFrame.fillna : Fill NaN values of a DataFrame.
22932293
Series.fillna : Fill NaN Values of a Series.
22942294
"""
2295-
value = self._validate_scalar(value)
2295+
value = self._require_scalar(value)
22962296
if self.hasnans:
22972297
result = self.putmask(self._isnan, value)
22982298
if downcast is None:
@@ -4140,7 +4140,7 @@ def _validate_fill_value(self, value):
41404140
return value
41414141

41424142
@final
4143-
def _validate_scalar(self, value):
4143+
def _require_scalar(self, value):
41444144
"""
41454145
Check that this is a scalar value that we can use for setitem-like
41464146
operations without changing dtype.

pandas/core/indexes/category.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ def astype(self, dtype, copy=True):
382382

383383
@doc(Index.fillna)
384384
def fillna(self, value, downcast=None):
385-
value = self._validate_scalar(value)
385+
value = self._require_scalar(value)
386386
cat = self._data.fillna(value)
387387
return type(self)._simple_new(cat, name=self.name)
388388

pandas/core/indexes/datetimelike.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ def _get_insert_freq(self, loc, item):
581581
"""
582582
Find the `freq` for self.insert(loc, item).
583583
"""
584-
value = self._data._validate_insert_value(item)
584+
value = self._data._validate_scalar(item)
585585
item = self._data._box_func(value)
586586

587587
freq = None

pandas/core/indexes/extension.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ def insert(self, loc: int, item):
335335
ValueError if the item is not valid for this dtype.
336336
"""
337337
arr = self._data
338-
code = arr._validate_insert_value(item)
338+
code = arr._validate_scalar(item)
339339

340340
new_vals = np.concatenate((arr._ndarray[:loc], [code], arr._ndarray[loc:]))
341341
new_arr = arr._from_backing_data(new_vals)

pandas/core/indexes/interval.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ def insert(self, loc, item):
903903
-------
904904
IntervalIndex
905905
"""
906-
left_insert, right_insert = self._data._validate_insert_value(item)
906+
left_insert, right_insert = self._data._validate_scalar(item)
907907

908908
new_left = self.left.insert(loc, left_insert)
909909
new_right = self.right.insert(loc, right_insert)

pandas/core/indexes/timedeltas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def get_loc(self, key, method=None, tolerance=None):
215215
raise InvalidIndexError(key)
216216

217217
try:
218-
key = self._data._validate_scalar(key)
218+
key = self._data._validate_scalar(key, unbox=False)
219219
except TypeError as err:
220220
raise KeyError(key) from err
221221

0 commit comments

Comments
 (0)