Skip to content

Commit d062d9e

Browse files
authored
REF: move np_can_hold_element to mgr method (#45453)
1 parent 59ba159 commit d062d9e

File tree

3 files changed

+20
-22
lines changed

3 files changed

+20
-22
lines changed

pandas/core/frame.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393
)
9494

9595
from pandas.core.dtypes.cast import (
96-
can_hold_element,
9796
construct_1d_arraylike_from_scalar,
9897
construct_2d_arraylike_from_scalar,
9998
find_common_type,
@@ -3882,18 +3881,11 @@ def _set_value(
38823881

38833882
series = self._get_item_cache(col)
38843883
loc = self.index.get_loc(index)
3885-
dtype = series.dtype
3886-
if isinstance(dtype, np.dtype) and dtype.kind not in ["m", "M"]:
3887-
# otherwise we have EA values, and this check will be done
3888-
# via setitem_inplace
3889-
if not can_hold_element(series._values, value):
3890-
# We'll go through loc and end up casting.
3891-
raise TypeError
3892-
3893-
series._mgr.setitem_inplace(loc, value)
3894-
# Note: trying to use series._set_value breaks tests in
3895-
# tests.frame.indexing.test_indexing and tests.indexing.test_partial
3896-
except (KeyError, TypeError):
3884+
3885+
# series._set_value will do validation that may raise TypeError
3886+
# or ValueError
3887+
series._set_value(loc, value, takeable=True)
3888+
except (KeyError, TypeError, ValueError):
38973889
# set using a non-recursive method & reset the cache
38983890
if takeable:
38993891
self.iloc[index, col] = value

pandas/core/internals/base.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@
99
final,
1010
)
1111

12+
import numpy as np
13+
1214
from pandas._typing import (
1315
ArrayLike,
1416
DtypeObj,
1517
Shape,
1618
)
1719
from pandas.errors import AbstractMethodError
1820

19-
from pandas.core.dtypes.cast import find_common_type
21+
from pandas.core.dtypes.cast import (
22+
find_common_type,
23+
np_can_hold_element,
24+
)
2025

2126
from pandas.core.base import PandasObject
2227
from pandas.core.indexes.api import (
@@ -171,7 +176,15 @@ def setitem_inplace(self, indexer, value) -> None:
171176
in place, not returning a new Manager (and Block), and thus never changing
172177
the dtype.
173178
"""
174-
self.array[indexer] = value
179+
arr = self.array
180+
181+
# EAs will do this validation in their own __setitem__ methods.
182+
if isinstance(arr, np.ndarray):
183+
# Note: checking for ndarray instead of np.dtype means we exclude
184+
# dt64/td64, which do their own validation.
185+
value = np_can_hold_element(arr.dtype, value)
186+
187+
arr[indexer] = value
175188

176189
def grouped_reduce(self, func, ignore_failures: bool = False):
177190
"""

pandas/core/series.py

-7
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
)
6363

6464
from pandas.core.dtypes.cast import (
65-
can_hold_element,
6665
convert_dtypes,
6766
maybe_box_native,
6867
maybe_cast_pointwise_result,
@@ -1151,12 +1150,6 @@ def __setitem__(self, key, value) -> None:
11511150

11521151
def _set_with_engine(self, key, value) -> None:
11531152
loc = self.index.get_loc(key)
1154-
dtype = self.dtype
1155-
if isinstance(dtype, np.dtype) and dtype.kind not in ["m", "M"]:
1156-
# otherwise we have EA values, and this check will be done
1157-
# via setitem_inplace
1158-
if not can_hold_element(self._values, value):
1159-
raise ValueError
11601153

11611154
# this is equivalent to self._values[key] = value
11621155
self._mgr.setitem_inplace(loc, value)

0 commit comments

Comments
 (0)