Skip to content

Commit 85260bf

Browse files
authored
TYP: core/dtypes/cast.py (pandas-dev#37024)
1 parent 2806e7d commit 85260bf

File tree

1 file changed

+70
-28
lines changed

1 file changed

+70
-28
lines changed

pandas/core/dtypes/cast.py

+70-28
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@
44

55
from contextlib import suppress
66
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+
)
819

920
import numpy as np
1021

@@ -21,7 +32,7 @@
2132
ints_to_pytimedelta,
2233
)
2334
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
2536
from pandas.util._validators import validate_bool_kwarg
2637

2738
from pandas.core.dtypes.common import (
@@ -86,6 +97,8 @@
8697
if TYPE_CHECKING:
8798
from pandas import Series
8899
from pandas.core.arrays import ExtensionArray
100+
from pandas.core.indexes.base import Index
101+
from pandas.core.indexes.datetimes import DatetimeIndex
89102

90103
_int8_max = np.iinfo(np.int8).max
91104
_int16_max = np.iinfo(np.int16).max
@@ -121,7 +134,7 @@ def is_nested_object(obj) -> bool:
121134
return False
122135

123136

124-
def maybe_downcast_to_dtype(result, dtype):
137+
def maybe_downcast_to_dtype(result, dtype: Dtype):
125138
"""
126139
try to cast to the specified dtype (e.g. convert back to bool/int
127140
or could be an astype of float64->float32
@@ -186,7 +199,7 @@ def maybe_downcast_to_dtype(result, dtype):
186199
return result
187200

188201

189-
def maybe_downcast_numeric(result, dtype, do_round: bool = False):
202+
def maybe_downcast_numeric(result, dtype: DtypeObj, do_round: bool = False):
190203
"""
191204
Subset of maybe_downcast_to_dtype restricted to numeric dtypes.
192205
@@ -329,7 +342,9 @@ def maybe_cast_result_dtype(dtype: DtypeObj, how: str) -> DtypeObj:
329342
return dtype
330343

331344

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:
333348
"""
334349
Call to `_from_sequence` that returns the object unchanged on Exception.
335350
@@ -362,7 +377,9 @@ def maybe_cast_to_extension_array(cls: Type["ExtensionArray"], obj, dtype=None):
362377
return result
363378

364379

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]:
366383
"""
367384
A safe version of putmask that potentially upcasts the result.
368385
@@ -444,7 +461,9 @@ def changeit():
444461
return result, False
445462

446463

447-
def maybe_casted_values(index, codes=None):
464+
def maybe_casted_values(
465+
index: "Index", codes: Optional[np.ndarray] = None
466+
) -> ArrayLike:
448467
"""
449468
Convert an index, given directly or as a pair (level, code), to a 1D array.
450469
@@ -468,7 +487,7 @@ def maybe_casted_values(index, codes=None):
468487

469488
# if we have the codes, extract the values with a mask
470489
if codes is not None:
471-
mask = codes == -1
490+
mask: np.ndarray = codes == -1
472491

473492
# we can have situations where the whole mask is -1,
474493
# meaning there is nothing found in codes, so make all nan's
@@ -660,7 +679,7 @@ def maybe_promote(dtype, fill_value=np.nan):
660679
return dtype, fill_value
661680

662681

663-
def _ensure_dtype_type(value, dtype):
682+
def _ensure_dtype_type(value, dtype: DtypeObj):
664683
"""
665684
Ensure that the given value is an instance of the given dtype.
666685
@@ -786,8 +805,9 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> Tuple[DtypeObj,
786805
return dtype, val
787806

788807

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]:
791811
"""
792812
Infer the dtype from an array.
793813
@@ -875,7 +895,12 @@ def maybe_infer_dtype_type(element):
875895
return tipo
876896

877897

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]:
879904
"""
880905
Provide explicit type promotion and coercion.
881906
@@ -887,6 +912,13 @@ def maybe_upcast(values, fill_value=np.nan, dtype=None, copy: bool = False):
887912
dtype : if None, then use the dtype of the values, else coerce to this type
888913
copy : bool, default True
889914
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
890922
"""
891923
if not is_scalar(fill_value) and not is_object_dtype(values.dtype):
892924
# 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):
907939
return values, fill_value
908940

909941

910-
def invalidate_string_dtypes(dtype_set):
942+
def invalidate_string_dtypes(dtype_set: Set[DtypeObj]):
911943
"""
912944
Change string like dtypes to object for
913945
``DataFrame.select_dtypes()``.
@@ -929,7 +961,7 @@ def coerce_indexer_dtype(indexer, categories):
929961
return ensure_int64(indexer)
930962

931963

932-
def coerce_to_dtypes(result, dtypes):
964+
def coerce_to_dtypes(result: Sequence[Scalar], dtypes: Sequence[Dtype]) -> List[Scalar]:
933965
"""
934966
given a dtypes and a result set, coerce the result elements to the
935967
dtypes
@@ -959,7 +991,9 @@ def conv(r, dtype):
959991
return [conv(r, dtype) for r, dtype in zip(result, dtypes)]
960992

961993

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:
963997
"""
964998
Cast the elements of an array to a given dtype a nan-safe manner.
965999
@@ -1063,7 +1097,9 @@ def astype_nansafe(arr, dtype, copy: bool = True, skipna: bool = False):
10631097
return arr.view(dtype)
10641098

10651099

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"]:
10671103
"""
10681104
If we have an object dtype array, try to coerce dates and/or numbers.
10691105
@@ -1184,7 +1220,7 @@ def soft_convert_objects(
11841220

11851221

11861222
def convert_dtypes(
1187-
input_array,
1223+
input_array: AnyArrayLike,
11881224
convert_string: bool = True,
11891225
convert_integer: bool = True,
11901226
convert_boolean: bool = True,
@@ -1195,7 +1231,7 @@ def convert_dtypes(
11951231
11961232
Parameters
11971233
----------
1198-
input_array : ExtensionArray or PandasArray
1234+
input_array : ExtensionArray, Index, Series or np.ndarray
11991235
convert_string : bool, default True
12001236
Whether object dtypes should be converted to ``StringDtype()``.
12011237
convert_integer : bool, default True
@@ -1250,9 +1286,11 @@ def convert_dtypes(
12501286
return inferred_dtype
12511287

12521288

1253-
def maybe_castable(arr) -> bool:
1289+
def maybe_castable(arr: np.ndarray) -> bool:
12541290
# return False to force a non-fastpath
12551291

1292+
assert isinstance(arr, np.ndarray) # GH 37024
1293+
12561294
# check datetime64[ns]/timedelta64[ns] are valid
12571295
# otherwise try to coerce
12581296
kind = arr.dtype.kind
@@ -1264,7 +1302,9 @@ def maybe_castable(arr) -> bool:
12641302
return arr.dtype.name not in POSSIBLY_CAST_DTYPES
12651303

12661304

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+
):
12681308
"""
12691309
we might have a array (or single object) that is datetime like,
12701310
and no dtype is passed don't change the value unless we find a
@@ -1371,7 +1411,7 @@ def try_timedelta(v):
13711411
return value
13721412

13731413

1374-
def maybe_cast_to_datetime(value, dtype, errors: str = "raise"):
1414+
def maybe_cast_to_datetime(value, dtype: DtypeObj, errors: str = "raise"):
13751415
"""
13761416
try to cast the array/value to a datetimelike dtype, converting float
13771417
nan to iNaT
@@ -1564,7 +1604,9 @@ def find_common_type(types: List[DtypeObj]) -> DtypeObj:
15641604
return np.find_common_type(types, [])
15651605

15661606

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:
15681610
"""
15691611
Create np.ndarray of specified shape and dtype, filled with values.
15701612
@@ -1592,7 +1634,7 @@ def cast_scalar_to_array(shape, value, dtype: Optional[DtypeObj] = None) -> np.n
15921634

15931635

15941636
def construct_1d_arraylike_from_scalar(
1595-
value, length: int, dtype: DtypeObj
1637+
value: Scalar, length: int, dtype: DtypeObj
15961638
) -> ArrayLike:
15971639
"""
15981640
create a np.ndarray / pandas type of specified shape and dtype
@@ -1636,7 +1678,7 @@ def construct_1d_arraylike_from_scalar(
16361678
return subarr
16371679

16381680

1639-
def construct_1d_object_array_from_listlike(values) -> np.ndarray:
1681+
def construct_1d_object_array_from_listlike(values: Sized) -> np.ndarray:
16401682
"""
16411683
Transform any list-like object in a 1-dimensional numpy array of object
16421684
dtype.
@@ -1662,7 +1704,7 @@ def construct_1d_object_array_from_listlike(values) -> np.ndarray:
16621704

16631705

16641706
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
16661708
) -> np.ndarray:
16671709
"""
16681710
Construct a new ndarray, coercing `values` to `dtype`, preserving NA.
@@ -1696,7 +1738,7 @@ def construct_1d_ndarray_preserving_na(
16961738
return subarr
16971739

16981740

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):
17001742
"""
17011743
Takes any dtype and returns the casted version, raising for when data is
17021744
incompatible with integer/unsigned integer dtypes.
@@ -1768,7 +1810,7 @@ def maybe_cast_to_integer_array(arr, dtype, copy: bool = False):
17681810
raise ValueError("Trying to coerce float values to integers")
17691811

17701812

1771-
def convert_scalar_for_putitemlike(scalar, dtype: np.dtype):
1813+
def convert_scalar_for_putitemlike(scalar: Scalar, dtype: np.dtype) -> Scalar:
17721814
"""
17731815
Convert datetimelike scalar if we are setting into a datetime64
17741816
or timedelta64 ndarray.
@@ -1799,7 +1841,7 @@ def convert_scalar_for_putitemlike(scalar, dtype: np.dtype):
17991841
return scalar
18001842

18011843

1802-
def validate_numeric_casting(dtype: np.dtype, value):
1844+
def validate_numeric_casting(dtype: np.dtype, value: Scalar) -> None:
18031845
"""
18041846
Check that we can losslessly insert the given value into an array
18051847
with the given dtype.

0 commit comments

Comments
 (0)