4
4
5
5
from contextlib import suppress
6
6
from datetime import date , datetime , timedelta
7
- from typing import TYPE_CHECKING , Any , List , Optional , Tuple , Type
7
+ from typing import (
8
+ TYPE_CHECKING ,
9
+ Any ,
10
+ List ,
11
+ Optional ,
12
+ Sequence ,
13
+ Set ,
14
+ Sized ,
15
+ Tuple ,
16
+ Type ,
17
+ Union ,
18
+ )
8
19
9
20
import numpy as np
10
21
21
32
ints_to_pytimedelta ,
22
33
)
23
34
from pandas ._libs .tslibs .timezones import tz_compare
24
- from pandas ._typing import ArrayLike , Dtype , DtypeObj
35
+ from pandas ._typing import AnyArrayLike , ArrayLike , Dtype , DtypeObj , Scalar
25
36
from pandas .util ._validators import validate_bool_kwarg
26
37
27
38
from pandas .core .dtypes .common import (
86
97
if TYPE_CHECKING :
87
98
from pandas import Series
88
99
from pandas .core .arrays import ExtensionArray
100
+ from pandas .core .indexes .base import Index
101
+ from pandas .core .indexes .datetimes import DatetimeIndex
89
102
90
103
_int8_max = np .iinfo (np .int8 ).max
91
104
_int16_max = np .iinfo (np .int16 ).max
@@ -121,7 +134,7 @@ def is_nested_object(obj) -> bool:
121
134
return False
122
135
123
136
124
- def maybe_downcast_to_dtype (result , dtype ):
137
+ def maybe_downcast_to_dtype (result , dtype : Dtype ):
125
138
"""
126
139
try to cast to the specified dtype (e.g. convert back to bool/int
127
140
or could be an astype of float64->float32
@@ -186,7 +199,7 @@ def maybe_downcast_to_dtype(result, dtype):
186
199
return result
187
200
188
201
189
- def maybe_downcast_numeric (result , dtype , do_round : bool = False ):
202
+ def maybe_downcast_numeric (result , dtype : DtypeObj , do_round : bool = False ):
190
203
"""
191
204
Subset of maybe_downcast_to_dtype restricted to numeric dtypes.
192
205
@@ -329,7 +342,9 @@ def maybe_cast_result_dtype(dtype: DtypeObj, how: str) -> DtypeObj:
329
342
return dtype
330
343
331
344
332
- def maybe_cast_to_extension_array (cls : Type ["ExtensionArray" ], obj , dtype = None ):
345
+ def maybe_cast_to_extension_array (
346
+ cls : Type ["ExtensionArray" ], obj : ArrayLike , dtype : Optional [ExtensionDtype ] = None
347
+ ) -> ArrayLike :
333
348
"""
334
349
Call to `_from_sequence` that returns the object unchanged on Exception.
335
350
@@ -362,7 +377,9 @@ def maybe_cast_to_extension_array(cls: Type["ExtensionArray"], obj, dtype=None):
362
377
return result
363
378
364
379
365
- def maybe_upcast_putmask (result : np .ndarray , mask : np .ndarray , other ):
380
+ def maybe_upcast_putmask (
381
+ result : np .ndarray , mask : np .ndarray , other : Scalar
382
+ ) -> Tuple [np .ndarray , bool ]:
366
383
"""
367
384
A safe version of putmask that potentially upcasts the result.
368
385
@@ -444,7 +461,9 @@ def changeit():
444
461
return result , False
445
462
446
463
447
- def maybe_casted_values (index , codes = None ):
464
+ def maybe_casted_values (
465
+ index : "Index" , codes : Optional [np .ndarray ] = None
466
+ ) -> ArrayLike :
448
467
"""
449
468
Convert an index, given directly or as a pair (level, code), to a 1D array.
450
469
@@ -468,7 +487,7 @@ def maybe_casted_values(index, codes=None):
468
487
469
488
# if we have the codes, extract the values with a mask
470
489
if codes is not None :
471
- mask = codes == - 1
490
+ mask : np . ndarray = codes == - 1
472
491
473
492
# we can have situations where the whole mask is -1,
474
493
# meaning there is nothing found in codes, so make all nan's
@@ -660,7 +679,7 @@ def maybe_promote(dtype, fill_value=np.nan):
660
679
return dtype , fill_value
661
680
662
681
663
- def _ensure_dtype_type (value , dtype ):
682
+ def _ensure_dtype_type (value , dtype : DtypeObj ):
664
683
"""
665
684
Ensure that the given value is an instance of the given dtype.
666
685
@@ -786,8 +805,9 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> Tuple[DtypeObj,
786
805
return dtype , val
787
806
788
807
789
- # TODO: try to make the Any in the return annotation more specific
790
- def infer_dtype_from_array (arr , pandas_dtype : bool = False ) -> Tuple [DtypeObj , Any ]:
808
+ def infer_dtype_from_array (
809
+ arr , pandas_dtype : bool = False
810
+ ) -> Tuple [DtypeObj , ArrayLike ]:
791
811
"""
792
812
Infer the dtype from an array.
793
813
@@ -875,7 +895,12 @@ def maybe_infer_dtype_type(element):
875
895
return tipo
876
896
877
897
878
- def maybe_upcast (values , fill_value = np .nan , dtype = None , copy : bool = False ):
898
+ def maybe_upcast (
899
+ values : ArrayLike ,
900
+ fill_value : Scalar = np .nan ,
901
+ dtype : Dtype = None ,
902
+ copy : bool = False ,
903
+ ) -> Tuple [ArrayLike , Scalar ]:
879
904
"""
880
905
Provide explicit type promotion and coercion.
881
906
@@ -887,6 +912,13 @@ def maybe_upcast(values, fill_value=np.nan, dtype=None, copy: bool = False):
887
912
dtype : if None, then use the dtype of the values, else coerce to this type
888
913
copy : bool, default True
889
914
If True always make a copy even if no upcast is required.
915
+
916
+ Returns
917
+ -------
918
+ values: ndarray or ExtensionArray
919
+ the original array, possibly upcast
920
+ fill_value:
921
+ the fill value, possibly upcast
890
922
"""
891
923
if not is_scalar (fill_value ) and not is_object_dtype (values .dtype ):
892
924
# We allow arbitrary fill values for object dtype
@@ -907,7 +939,7 @@ def maybe_upcast(values, fill_value=np.nan, dtype=None, copy: bool = False):
907
939
return values , fill_value
908
940
909
941
910
- def invalidate_string_dtypes (dtype_set ):
942
+ def invalidate_string_dtypes (dtype_set : Set [ DtypeObj ] ):
911
943
"""
912
944
Change string like dtypes to object for
913
945
``DataFrame.select_dtypes()``.
@@ -929,7 +961,7 @@ def coerce_indexer_dtype(indexer, categories):
929
961
return ensure_int64 (indexer )
930
962
931
963
932
- def coerce_to_dtypes (result , dtypes ) :
964
+ def coerce_to_dtypes (result : Sequence [ Scalar ] , dtypes : Sequence [ Dtype ]) -> List [ Scalar ] :
933
965
"""
934
966
given a dtypes and a result set, coerce the result elements to the
935
967
dtypes
@@ -959,7 +991,9 @@ def conv(r, dtype):
959
991
return [conv (r , dtype ) for r , dtype in zip (result , dtypes )]
960
992
961
993
962
- def astype_nansafe (arr , dtype , copy : bool = True , skipna : bool = False ):
994
+ def astype_nansafe (
995
+ arr , dtype : DtypeObj , copy : bool = True , skipna : bool = False
996
+ ) -> ArrayLike :
963
997
"""
964
998
Cast the elements of an array to a given dtype a nan-safe manner.
965
999
@@ -1063,7 +1097,9 @@ def astype_nansafe(arr, dtype, copy: bool = True, skipna: bool = False):
1063
1097
return arr .view (dtype )
1064
1098
1065
1099
1066
- def maybe_convert_objects (values : np .ndarray , convert_numeric : bool = True ):
1100
+ def maybe_convert_objects (
1101
+ values : np .ndarray , convert_numeric : bool = True
1102
+ ) -> Union [np .ndarray , "DatetimeIndex" ]:
1067
1103
"""
1068
1104
If we have an object dtype array, try to coerce dates and/or numbers.
1069
1105
@@ -1184,7 +1220,7 @@ def soft_convert_objects(
1184
1220
1185
1221
1186
1222
def convert_dtypes (
1187
- input_array ,
1223
+ input_array : AnyArrayLike ,
1188
1224
convert_string : bool = True ,
1189
1225
convert_integer : bool = True ,
1190
1226
convert_boolean : bool = True ,
@@ -1195,7 +1231,7 @@ def convert_dtypes(
1195
1231
1196
1232
Parameters
1197
1233
----------
1198
- input_array : ExtensionArray or PandasArray
1234
+ input_array : ExtensionArray, Index, Series or np.ndarray
1199
1235
convert_string : bool, default True
1200
1236
Whether object dtypes should be converted to ``StringDtype()``.
1201
1237
convert_integer : bool, default True
@@ -1250,9 +1286,11 @@ def convert_dtypes(
1250
1286
return inferred_dtype
1251
1287
1252
1288
1253
- def maybe_castable (arr ) -> bool :
1289
+ def maybe_castable (arr : np . ndarray ) -> bool :
1254
1290
# return False to force a non-fastpath
1255
1291
1292
+ assert isinstance (arr , np .ndarray ) # GH 37024
1293
+
1256
1294
# check datetime64[ns]/timedelta64[ns] are valid
1257
1295
# otherwise try to coerce
1258
1296
kind = arr .dtype .kind
@@ -1264,7 +1302,9 @@ def maybe_castable(arr) -> bool:
1264
1302
return arr .dtype .name not in POSSIBLY_CAST_DTYPES
1265
1303
1266
1304
1267
- def maybe_infer_to_datetimelike (value , convert_dates : bool = False ):
1305
+ def maybe_infer_to_datetimelike (
1306
+ value : Union [ArrayLike , Scalar ], convert_dates : bool = False
1307
+ ):
1268
1308
"""
1269
1309
we might have a array (or single object) that is datetime like,
1270
1310
and no dtype is passed don't change the value unless we find a
@@ -1371,7 +1411,7 @@ def try_timedelta(v):
1371
1411
return value
1372
1412
1373
1413
1374
- def maybe_cast_to_datetime (value , dtype , errors : str = "raise" ):
1414
+ def maybe_cast_to_datetime (value , dtype : DtypeObj , errors : str = "raise" ):
1375
1415
"""
1376
1416
try to cast the array/value to a datetimelike dtype, converting float
1377
1417
nan to iNaT
@@ -1564,7 +1604,9 @@ def find_common_type(types: List[DtypeObj]) -> DtypeObj:
1564
1604
return np .find_common_type (types , [])
1565
1605
1566
1606
1567
- def cast_scalar_to_array (shape , value , dtype : Optional [DtypeObj ] = None ) -> np .ndarray :
1607
+ def cast_scalar_to_array (
1608
+ shape : Tuple , value : Scalar , dtype : Optional [DtypeObj ] = None
1609
+ ) -> np .ndarray :
1568
1610
"""
1569
1611
Create np.ndarray of specified shape and dtype, filled with values.
1570
1612
@@ -1592,7 +1634,7 @@ def cast_scalar_to_array(shape, value, dtype: Optional[DtypeObj] = None) -> np.n
1592
1634
1593
1635
1594
1636
def construct_1d_arraylike_from_scalar (
1595
- value , length : int , dtype : DtypeObj
1637
+ value : Scalar , length : int , dtype : DtypeObj
1596
1638
) -> ArrayLike :
1597
1639
"""
1598
1640
create a np.ndarray / pandas type of specified shape and dtype
@@ -1636,7 +1678,7 @@ def construct_1d_arraylike_from_scalar(
1636
1678
return subarr
1637
1679
1638
1680
1639
- def construct_1d_object_array_from_listlike (values ) -> np .ndarray :
1681
+ def construct_1d_object_array_from_listlike (values : Sized ) -> np .ndarray :
1640
1682
"""
1641
1683
Transform any list-like object in a 1-dimensional numpy array of object
1642
1684
dtype.
@@ -1662,7 +1704,7 @@ def construct_1d_object_array_from_listlike(values) -> np.ndarray:
1662
1704
1663
1705
1664
1706
def construct_1d_ndarray_preserving_na (
1665
- values , dtype : Optional [DtypeObj ] = None , copy : bool = False
1707
+ values : Sequence , dtype : Optional [DtypeObj ] = None , copy : bool = False
1666
1708
) -> np .ndarray :
1667
1709
"""
1668
1710
Construct a new ndarray, coercing `values` to `dtype`, preserving NA.
@@ -1696,7 +1738,7 @@ def construct_1d_ndarray_preserving_na(
1696
1738
return subarr
1697
1739
1698
1740
1699
- def maybe_cast_to_integer_array (arr , dtype , copy : bool = False ):
1741
+ def maybe_cast_to_integer_array (arr , dtype : Dtype , copy : bool = False ):
1700
1742
"""
1701
1743
Takes any dtype and returns the casted version, raising for when data is
1702
1744
incompatible with integer/unsigned integer dtypes.
@@ -1768,7 +1810,7 @@ def maybe_cast_to_integer_array(arr, dtype, copy: bool = False):
1768
1810
raise ValueError ("Trying to coerce float values to integers" )
1769
1811
1770
1812
1771
- def convert_scalar_for_putitemlike (scalar , dtype : np .dtype ):
1813
+ def convert_scalar_for_putitemlike (scalar : Scalar , dtype : np .dtype ) -> Scalar :
1772
1814
"""
1773
1815
Convert datetimelike scalar if we are setting into a datetime64
1774
1816
or timedelta64 ndarray.
@@ -1799,7 +1841,7 @@ def convert_scalar_for_putitemlike(scalar, dtype: np.dtype):
1799
1841
return scalar
1800
1842
1801
1843
1802
- def validate_numeric_casting (dtype : np .dtype , value ) :
1844
+ def validate_numeric_casting (dtype : np .dtype , value : Scalar ) -> None :
1803
1845
"""
1804
1846
Check that we can losslessly insert the given value into an array
1805
1847
with the given dtype.
0 commit comments