11from __future__ import annotations
22
3- from typing import overload
3+ from typing import (
4+ Optional ,
5+ overload ,
6+ )
47import warnings
58
69import numpy as np
3235 is_integer_dtype ,
3336 is_list_like ,
3437 is_object_dtype ,
38+ is_string_dtype ,
3539 pandas_dtype ,
3640)
3741from pandas .core .dtypes .missing import isna
@@ -119,17 +123,20 @@ def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None:
119123 return None
120124
121125
122- def safe_cast (values , dtype , copy : bool ):
126+ def safe_cast (values , dtype , inferred_type : str | None , copy : bool ):
123127 """
124128 Safely cast the values to the dtype if they
125129 are equivalent, meaning floats must be equivalent to the
126130 ints.
127-
128131 """
132+ if inferred_type in ("string" , "unicode" ):
133+ # casts from str are always safe since they raise
134+ # a ValueError if the str cannot be parsed into an int
135+ return values .astype (dtype , copy = copy )
136+
129137 try :
130138 return values .astype (dtype , casting = "safe" , copy = copy )
131139 except TypeError as err :
132-
133140 casted = values .astype (dtype , copy = copy )
134141 if (casted == values ).all ():
135142 return casted
@@ -143,7 +150,7 @@ def coerce_to_array(
143150 values , dtype , mask = None , copy : bool = False
144151) -> tuple [np .ndarray , np .ndarray ]:
145152 """
146- Coerce the input values array to numpy arrays with a mask
153+ Coerce the input values array to numpy arrays with a mask.
147154
148155 Parameters
149156 ----------
@@ -187,7 +194,9 @@ def coerce_to_array(
187194 return values , mask
188195
189196 values = np .array (values , copy = copy )
190- if is_object_dtype (values ):
197+ inferred_type = None
198+ # note that `is_string_dtype` subsumes `is_object_dtype`
199+ if is_string_dtype (values ):
191200 inferred_type = lib .infer_dtype (values , skipna = True )
192201 if inferred_type == "empty" :
193202 values = np .empty (len (values ))
@@ -198,6 +207,8 @@ def coerce_to_array(
198207 "mixed-integer" ,
199208 "integer-na" ,
200209 "mixed-integer-float" ,
210+ "string" ,
211+ "unicode" ,
201212 ]:
202213 raise TypeError (f"{ values .dtype } cannot be converted to an IntegerDtype" )
203214
@@ -230,9 +241,7 @@ def coerce_to_array(
230241 if mask .any ():
231242 values = values .copy ()
232243 values [mask ] = 1
233- values = safe_cast (values , dtype , copy = False )
234- else :
235- values = safe_cast (values , dtype , copy = False )
244+ values = safe_cast (values , dtype , inferred_type , copy = False )
236245
237246 return values , mask
238247
0 commit comments