diff --git a/pandas/_libs/writers.pyx b/pandas/_libs/writers.pyx index 6577f3604d14b..6adda1fe92044 100644 --- a/pandas/_libs/writers.pyx +++ b/pandas/_libs/writers.pyx @@ -34,7 +34,7 @@ def write_csv_rows( data_index : ndarray nlevels : int cols : ndarray - writer : object + writer : _csv.writer """ # In crude testing, N>100 yields little marginal improvement cdef: diff --git a/pandas/core/array_algos/quantile.py b/pandas/core/array_algos/quantile.py index f140ee08aef05..eb96c14286715 100644 --- a/pandas/core/array_algos/quantile.py +++ b/pandas/core/array_algos/quantile.py @@ -142,17 +142,10 @@ def quantile_ea_compat( mask = np.asarray(values.isna()) mask = np.atleast_2d(mask) - # error: Incompatible types in assignment (expression has type "ndarray", variable - # has type "ExtensionArray") - values, fill_value = values._values_for_factorize() # type: ignore[assignment] - # error: No overload variant of "atleast_2d" matches argument type "ExtensionArray" - values = np.atleast_2d(values) # type: ignore[call-overload] - - # error: Argument 1 to "quantile_with_mask" has incompatible type "ExtensionArray"; - # expected "ndarray" - result = quantile_with_mask( - values, mask, fill_value, qs, interpolation, axis # type: ignore[arg-type] - ) + arr, fill_value = values._values_for_factorize() + arr = np.atleast_2d(arr) + + result = quantile_with_mask(arr, mask, fill_value, qs, interpolation, axis) if not is_sparse(orig.dtype): # shape[0] should be 1 as long as EAs are 1D diff --git a/pandas/core/array_algos/replace.py b/pandas/core/array_algos/replace.py index 0bdfc8fdb95a5..201b9fdcc51cc 100644 --- a/pandas/core/array_algos/replace.py +++ b/pandas/core/array_algos/replace.py @@ -152,8 +152,6 @@ def re_replacer(s): f = np.vectorize(re_replacer, otypes=[values.dtype]) if mask is None: - # error: Invalid index type "slice" for "ExtensionArray"; expected type - # "Union[int, ndarray]" - values[:] = f(values) # type: ignore[index] + values[:] = f(values) else: values[mask] = f(values[mask]) diff --git a/pandas/core/array_algos/take.py b/pandas/core/array_algos/take.py index 31cbadb0e442b..c1abd8bbf39d0 100644 --- a/pandas/core/array_algos/take.py +++ b/pandas/core/array_algos/take.py @@ -177,9 +177,6 @@ def take_1d( Note: similarly to `take_nd`, this function assumes that the indexer is a valid(ated) indexer with no out of bound indices. - - TODO(ArrayManager): mainly useful for ArrayManager, otherwise can potentially - be removed again if we don't end up with ArrayManager. """ if not isinstance(arr, np.ndarray): # ExtensionArray -> dispatch to their method diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 68909e30650c7..c45528d657404 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -326,7 +326,7 @@ def __getitem__( """ raise AbstractMethodError(self) - def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: + def __setitem__(self, key: Union[int, slice, np.ndarray], value: Any) -> None: """ Set one or more values inplace. diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 96bba51f34c08..4a032c60d386d 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -7,9 +7,11 @@ tzinfo, ) from typing import ( + TYPE_CHECKING, Optional, Union, cast, + overload, ) import warnings @@ -79,6 +81,9 @@ Tick, ) +if TYPE_CHECKING: + from typing import Literal + _midnight = time(0, 0) @@ -1909,6 +1914,20 @@ def std( # Constructor Helpers +@overload +def sequence_to_datetimes( + data, allow_object: Literal[False] = ..., require_iso8601: bool = ... +) -> DatetimeArray: + ... + + +@overload +def sequence_to_datetimes( + data, allow_object: Literal[True] = ..., require_iso8601: bool = ... +) -> Union[np.ndarray, DatetimeArray]: + ... + + def sequence_to_datetimes( data, allow_object: bool = False, require_iso8601: bool = False ) -> Union[np.ndarray, DatetimeArray]: diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index 75d9fcd3b4965..7251faee333bb 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -9,6 +9,7 @@ Tuple, Type, Union, + cast, ) import numpy as np @@ -485,7 +486,7 @@ def _cmp_method(self, other, op): # TODO(ARROW-9429): Add a .to_numpy() to ChunkedArray return BooleanArray._from_sequence(result.to_pandas().values) - def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: + def __setitem__(self, key: Union[int, slice, np.ndarray], value: Any) -> None: """Set one or more values inplace. Parameters @@ -509,6 +510,8 @@ def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: key = check_array_indexer(self, key) if is_integer(key): + key = cast(int, key) + if not is_scalar(value): raise ValueError("Must pass scalars with scalar indexer") elif isna(value): @@ -518,8 +521,7 @@ def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: # Slice data and insert in-between new_data = [ - # error: Slice index must be an integer or None - *self._data[0:key].chunks, # type: ignore[misc] + *self._data[0:key].chunks, pa.array([value], type=pa.string()), *self._data[(key + 1) :].chunks, ] @@ -530,11 +532,11 @@ def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: # This is probably extremely slow. # Convert all possible input key types to an array of integers - if is_bool_dtype(key): + if isinstance(key, slice): + key_array = np.array(range(len(self))[key]) + elif is_bool_dtype(key): # TODO(ARROW-9430): Directly support setitem(booleans) key_array = np.argwhere(key).flatten() - elif isinstance(key, slice): - key_array = np.array(range(len(self))[key]) else: # TODO(ARROW-9431): Directly support setitem(integers) key_array = np.asanyarray(key) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index be535495de8d0..7a2175a364a8a 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -44,7 +44,6 @@ ) from pandas._libs.tslibs.timedeltas import array_to_timedelta64 from pandas._typing import ( - AnyArrayLike, ArrayLike, Dtype, DtypeObj, @@ -407,27 +406,16 @@ def maybe_cast_result( assert not is_scalar(result) - if ( - is_extension_array_dtype(dtype) - and not is_categorical_dtype(dtype) - and dtype.kind != "M" - ): - # We have to special case categorical so as not to upcast - # things like counts back to categorical - - # error: Item "dtype[Any]" of "Union[dtype[Any], ExtensionDtype]" has no - # attribute "construct_array_type" - cls = dtype.construct_array_type() # type: ignore[union-attr] - # error: Argument "dtype" to "maybe_cast_to_extension_array" has incompatible - # type "Union[dtype[Any], ExtensionDtype]"; expected "Optional[ExtensionDtype]" - result = maybe_cast_to_extension_array( - cls, result, dtype=dtype # type: ignore[arg-type] - ) + if isinstance(dtype, ExtensionDtype): + if not is_categorical_dtype(dtype) and dtype.kind != "M": + # We have to special case categorical so as not to upcast + # things like counts back to categorical - elif numeric_only and is_numeric_dtype(dtype) or not numeric_only: - # error: Argument 2 to "maybe_downcast_to_dtype" has incompatible type - # "Union[dtype[Any], ExtensionDtype]"; expected "Union[str, dtype[Any]]" - result = maybe_downcast_to_dtype(result, dtype) # type: ignore[arg-type] + cls = dtype.construct_array_type() + result = maybe_cast_to_extension_array(cls, result, dtype=dtype) + + elif (numeric_only and is_numeric_dtype(dtype)) or not numeric_only: + result = maybe_downcast_to_dtype(result, dtype) return result @@ -549,17 +537,23 @@ def maybe_upcast_putmask(result: np.ndarray, mask: np.ndarray) -> np.ndarray: new_dtype = ensure_dtype_can_hold_na(result.dtype) if new_dtype != result.dtype: - # error: Argument 1 to "astype" of "_ArrayOrScalarCommon" has incompatible - # type "Union[dtype[Any], ExtensionDtype]"; expected "Union[dtype[Any], - # None, type, _SupportsDType, str, Union[Tuple[Any, int], Tuple[Any, - # Union[int, Sequence[int]]], List[Any], _DTypeDict, Tuple[Any, Any]]]" - result = result.astype(new_dtype, copy=True) # type: ignore[arg-type] + result = result.astype(new_dtype, copy=True) np.place(result, mask, np.nan) return result +@overload +def ensure_dtype_can_hold_na(dtype: np.dtype) -> np.dtype: + ... + + +@overload +def ensure_dtype_can_hold_na(dtype: ExtensionDtype) -> ExtensionDtype: + ... + + def ensure_dtype_can_hold_na(dtype: DtypeObj) -> DtypeObj: """ If we have a dtype that cannot hold NA values, find the best match that can. @@ -636,9 +630,7 @@ def _maybe_promote(dtype: np.dtype, fill_value=np.nan): kinds = ["i", "u", "f", "c", "m", "M"] if is_valid_na_for_dtype(fill_value, dtype) and dtype.kind in kinds: - # error: Incompatible types in assignment (expression has type - # "Union[dtype[Any], ExtensionDtype]", variable has type "dtype[Any]") - dtype = ensure_dtype_can_hold_na(dtype) # type: ignore[assignment] + dtype = ensure_dtype_can_hold_na(dtype) fv = na_value_for_dtype(dtype) return dtype, fv @@ -1471,7 +1463,7 @@ def soft_convert_objects( def convert_dtypes( - input_array: AnyArrayLike, + input_array: ArrayLike, convert_string: bool = True, convert_integer: bool = True, convert_boolean: bool = True, @@ -1483,7 +1475,7 @@ def convert_dtypes( Parameters ---------- - input_array : ExtensionArray, Index, Series or np.ndarray + input_array : ExtensionArray or np.ndarray convert_string : bool, default True Whether object dtypes should be converted to ``StringDtype()``. convert_integer : bool, default True @@ -1707,15 +1699,10 @@ def maybe_cast_to_datetime( # GH 25843: Remove tz information since the dtype # didn't specify one - # error: Item "ndarray" of "Union[ndarray, DatetimeArray]" - # has no attribute "tz" - if dta.tz is not None: # type: ignore[union-attr] + if dta.tz is not None: # equiv: dta.view(dtype) # Note: NOT equivalent to dta.astype(dtype) - - # error: Item "ndarray" of "Union[ndarray, - # DatetimeArray]" has no attribute "tz_localize" - dta = dta.tz_localize(None) # type: ignore[union-attr] + dta = dta.tz_localize(None) value = dta elif is_datetime64tz: dtype = cast(DatetimeTZDtype, dtype) @@ -1725,38 +1712,19 @@ def maybe_cast_to_datetime( # be localized to the timezone. is_dt_string = is_string_dtype(value.dtype) dta = sequence_to_datetimes(value, allow_object=False) - # error: Item "ndarray" of "Union[ndarray, DatetimeArray]" - # has no attribute "tz" - if dta.tz is not None: # type: ignore[union-attr] - # error: Argument 1 to "astype" of - # "_ArrayOrScalarCommon" has incompatible type - # "Union[dtype[Any], ExtensionDtype, None]"; expected - # "Union[dtype[Any], None, type, _SupportsDType, str, - # Union[Tuple[Any, int], Tuple[Any, Union[int, - # Sequence[int]]], List[Any], _DTypeDict, Tuple[Any, - # Any]]]" - value = dta.astype( - dtype, copy=False # type: ignore[arg-type] - ) + if dta.tz is not None: + value = dta.astype(dtype, copy=False) elif is_dt_string: # Strings here are naive, so directly localize # equiv: dta.astype(dtype) # though deprecated - # error: Item "ndarray" of "Union[ndarray, - # DatetimeArray]" has no attribute "tz_localize" - value = dta.tz_localize( # type: ignore[union-attr] - dtype.tz - ) + value = dta.tz_localize(dtype.tz) else: # Numeric values are UTC at this point, # so localize and convert # equiv: Series(dta).astype(dtype) # though deprecated - # error: Item "ndarray" of "Union[ndarray, - # DatetimeArray]" has no attribute "tz_localize" - value = dta.tz_localize( # type: ignore[union-attr] - "UTC" - ).tz_convert(dtype.tz) + value = dta.tz_localize("UTC").tz_convert(dtype.tz) elif is_timedelta64: # if successful, we get a ndarray[td64ns] value, _ = sequence_to_td64ns(value) @@ -1789,14 +1757,12 @@ def maybe_cast_to_datetime( elif value.dtype == object: value = maybe_infer_to_datetimelike(value) - elif not isinstance(value, ABCExtensionArray): + elif isinstance(value, list): # only do this if we have an array and the dtype of the array is not # setup already we are not an integer/object, so don't bother with this # conversion - # error: Argument 1 to "maybe_infer_to_datetimelike" has incompatible type - # "Union[ExtensionArray, List[Any]]"; expected "Union[ndarray, List[Any]]" - value = maybe_infer_to_datetimelike(value) # type: ignore[arg-type] + value = maybe_infer_to_datetimelike(value) return value @@ -1974,10 +1940,8 @@ def construct_1d_arraylike_from_scalar( except OutOfBoundsDatetime: dtype = np.dtype(object) - if is_extension_array_dtype(dtype): - # error: Item "dtype" of "Union[dtype, ExtensionDtype]" has no - # attribute "construct_array_type" - cls = dtype.construct_array_type() # type: ignore[union-attr] + if isinstance(dtype, ExtensionDtype): + cls = dtype.construct_array_type() subarr = cls._from_sequence([value] * length, dtype=dtype) else: @@ -1994,11 +1958,7 @@ def construct_1d_arraylike_from_scalar( elif dtype.kind in ["M", "m"]: value = maybe_unbox_datetimelike(value, dtype) - # error: Argument "dtype" to "empty" has incompatible type - # "Union[dtype, ExtensionDtype]"; expected "Union[dtype, None, type, - # _SupportsDtype, str, Tuple[Any, int], Tuple[Any, Union[int, - # Sequence[int]]], List[Any], _DtypeDict, Tuple[Any, Any]]" - subarr = np.empty(length, dtype=dtype) # type: ignore[arg-type] + subarr = np.empty(length, dtype=dtype) subarr.fill(value) return subarr diff --git a/pandas/core/dtypes/missing.py b/pandas/core/dtypes/missing.py index 9a72dee8d87ca..59d6f9a51ed43 100644 --- a/pandas/core/dtypes/missing.py +++ b/pandas/core/dtypes/missing.py @@ -38,6 +38,7 @@ is_string_like_dtype, needs_i8_conversion, ) +from pandas.core.dtypes.dtypes import ExtensionDtype from pandas.core.dtypes.generic import ( ABCDataFrame, ABCExtensionArray, @@ -232,49 +233,29 @@ def _isna_array(values: ArrayLike, inf_as_na: bool = False): """ dtype = values.dtype - if is_extension_array_dtype(dtype): + if not isinstance(values, np.ndarray): + # i.e. ExtensionArray if inf_as_na and is_categorical_dtype(dtype): - # error: Item "ndarray" of "Union[ExtensionArray, ndarray]" has no attribute - # "to_numpy" - result = libmissing.isnaobj_old( - values.to_numpy() # type: ignore[union-attr] - ) + result = libmissing.isnaobj_old(values.to_numpy()) else: - # error: Item "ndarray" of "Union[ExtensionArray, ndarray]" has no attribute - # "isna" - result = values.isna() # type: ignore[union-attr] + result = values.isna() elif is_string_dtype(dtype): - # error: Argument 1 to "_isna_string_dtype" has incompatible type - # "ExtensionArray"; expected "ndarray" - # error: Argument 2 to "_isna_string_dtype" has incompatible type - # "ExtensionDtype"; expected "dtype[Any]" - result = _isna_string_dtype( - values, dtype, inf_as_na=inf_as_na # type: ignore[arg-type] - ) + result = _isna_string_dtype(values, inf_as_na=inf_as_na) elif needs_i8_conversion(dtype): # this is the NaT pattern result = values.view("i8") == iNaT else: if inf_as_na: - # error: Argument 1 to "__call__" of "ufunc" has incompatible type - # "ExtensionArray"; expected "Union[Union[int, float, complex, str, bytes, - # generic], Sequence[Union[int, float, complex, str, bytes, generic]], - # Sequence[Sequence[Any]], _SupportsArray]" - result = ~np.isfinite(values) # type: ignore[arg-type] + result = ~np.isfinite(values) else: - # error: Argument 1 to "__call__" of "ufunc" has incompatible type - # "ExtensionArray"; expected "Union[Union[int, float, complex, str, bytes, - # generic], Sequence[Union[int, float, complex, str, bytes, generic]], - # Sequence[Sequence[Any]], _SupportsArray]" - result = np.isnan(values) # type: ignore[arg-type] + result = np.isnan(values) return result -def _isna_string_dtype( - values: np.ndarray, dtype: np.dtype, inf_as_na: bool -) -> np.ndarray: +def _isna_string_dtype(values: np.ndarray, inf_as_na: bool) -> np.ndarray: # Working around NumPy ticket 1542 + dtype = values.dtype shape = values.shape if is_string_like_dtype(dtype): @@ -592,10 +573,8 @@ def na_value_for_dtype(dtype: DtypeObj, compat: bool = True): numpy.datetime64('NaT') """ - if is_extension_array_dtype(dtype): - # error: Item "dtype[Any]" of "Union[dtype[Any], ExtensionDtype]" has no - # attribute "na_value" - return dtype.na_value # type: ignore[union-attr] + if isinstance(dtype, ExtensionDtype): + return dtype.na_value elif needs_i8_conversion(dtype): return dtype.type("NaT", "ns") elif is_float_dtype(dtype): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9fdd979ce8eca..2374cc0b6a8fa 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -719,9 +719,7 @@ def __init__( values, columns, index, columns, dtype=None, typ=manager ) else: - # error: Incompatible types in assignment (expression has type - # "ndarray", variable has type "List[ExtensionArray]") - values = construct_2d_arraylike_from_scalar( # type: ignore[assignment] + arr2d = construct_2d_arraylike_from_scalar( data, len(index), len(columns), @@ -730,11 +728,10 @@ def __init__( ) mgr = ndarray_to_mgr( - # error: "List[ExtensionArray]" has no attribute "dtype" - values, + arr2d, index, columns, - dtype=values.dtype, # type: ignore[attr-defined] + dtype=arr2d.dtype, copy=False, typ=manager, ) diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 002d989330160..4a08e733b770c 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -399,15 +399,15 @@ def dict_to_mgr( # no obvious "empty" int column if missing.any() and not is_integer_dtype(dtype): + nan_dtype: DtypeObj + if dtype is None or ( isinstance(dtype, np.dtype) and np.issubdtype(dtype, np.flexible) ): # GH#1783 nan_dtype = np.dtype("object") else: - # error: Incompatible types in assignment (expression has type - # "Union[dtype, ExtensionDtype]", variable has type "dtype") - nan_dtype = dtype # type: ignore[assignment] + nan_dtype = dtype val = construct_1d_arraylike_from_scalar(np.nan, len(index), nan_dtype) arrays.loc[missing] = [val] * missing.sum() @@ -727,27 +727,18 @@ def to_arrays( return arrays, columns if isinstance(data[0], (list, tuple)): - content = _list_to_arrays(data) + arr = _list_to_arrays(data) elif isinstance(data[0], abc.Mapping): - content, columns = _list_of_dict_to_arrays(data, columns) + arr, columns = _list_of_dict_to_arrays(data, columns) elif isinstance(data[0], ABCSeries): - content, columns = _list_of_series_to_arrays(data, columns) + arr, columns = _list_of_series_to_arrays(data, columns) else: # last ditch effort data = [tuple(x) for x in data] - content = _list_to_arrays(data) + arr = _list_to_arrays(data) - # error: Incompatible types in assignment (expression has type "List[ndarray]", - # variable has type "List[Union[Union[str, int, float, bool], Union[Any, Any, Any, - # Any]]]") - content, columns = _finalize_columns_and_data( # type: ignore[assignment] - content, columns, dtype - ) - # error: Incompatible return value type (got "Tuple[ndarray, Index]", expected - # "Tuple[List[ExtensionArray], Index]") - # error: Incompatible return value type (got "Tuple[ndarray, Index]", expected - # "Tuple[List[ndarray], Index]") - return content, columns # type: ignore[return-value] + content, columns = _finalize_columns_and_data(arr, columns, dtype) + return content, columns def _list_to_arrays(data: List[Union[Tuple, List]]) -> np.ndarray: @@ -838,38 +829,22 @@ def _finalize_columns_and_data( content: np.ndarray, # ndim == 2 columns: Optional[Index], dtype: Optional[DtypeObj], -) -> Tuple[List[np.ndarray], Index]: +) -> Tuple[List[ArrayLike], Index]: """ Ensure we have valid columns, cast object dtypes if possible. """ - # error: Incompatible types in assignment (expression has type "List[Any]", variable - # has type "ndarray") - content = list(content.T) # type: ignore[assignment] + contents = list(content.T) try: - # error: Argument 1 to "_validate_or_indexify_columns" has incompatible type - # "ndarray"; expected "List[Any]" - columns = _validate_or_indexify_columns( - content, columns # type: ignore[arg-type] - ) + columns = _validate_or_indexify_columns(contents, columns) except AssertionError as err: # GH#26429 do not raise user-facing AssertionError raise ValueError(err) from err - if len(content) and content[0].dtype == np.object_: - # error: Incompatible types in assignment (expression has type - # "List[Union[Union[str, int, float, bool], Union[Any, Any, Any, Any]]]", - # variable has type "ndarray") - # error: Argument 1 to "_convert_object_array" has incompatible type "ndarray"; - # expected "List[Union[Union[str, int, float, bool], Union[Any, Any, Any, - # Any]]]" - content = _convert_object_array( # type: ignore[assignment] - content, dtype=dtype # type: ignore[arg-type] - ) - # error: Incompatible return value type (got "Tuple[ndarray, Union[Index, - # List[Union[str, int]]]]", expected "Tuple[List[ndarray], Union[Index, - # List[Union[str, int]]]]") - return content, columns # type: ignore[return-value] + if len(contents) and contents[0].dtype == np.object_: + contents = _convert_object_array(contents, dtype=dtype) + + return contents, columns def _validate_or_indexify_columns( diff --git a/pandas/core/util/hashing.py b/pandas/core/util/hashing.py index 5e45d36e188a2..87be5c0997072 100644 --- a/pandas/core/util/hashing.py +++ b/pandas/core/util/hashing.py @@ -25,7 +25,6 @@ from pandas.core.dtypes.common import ( is_categorical_dtype, - is_extension_array_dtype, is_list_like, ) from pandas.core.dtypes.generic import ( @@ -119,9 +118,7 @@ def hash_pandas_object( h = hash_array(obj._values, encoding, hash_key, categorize).astype( "uint64", copy=False ) - # error: Incompatible types in assignment (expression has type "Series", - # variable has type "ndarray") - h = Series(h, index=obj, dtype="uint64", copy=False) # type: ignore[assignment] + ser = Series(h, index=obj, dtype="uint64", copy=False) elif isinstance(obj, ABCSeries): h = hash_array(obj._values, encoding, hash_key, categorize).astype( @@ -141,11 +138,7 @@ def hash_pandas_object( arrays = itertools.chain([h], index_iter) h = combine_hash_arrays(arrays, 2) - # error: Incompatible types in assignment (expression has type "Series", - # variable has type "ndarray") - h = Series( # type: ignore[assignment] - h, index=obj.index, dtype="uint64", copy=False - ) + ser = Series(h, index=obj.index, dtype="uint64", copy=False) elif isinstance(obj, ABCDataFrame): hashes = (hash_array(series._values) for _, series in obj.items()) @@ -168,15 +161,11 @@ def hash_pandas_object( hashes = (x for x in _hashes) h = combine_hash_arrays(hashes, num_items) - # error: Incompatible types in assignment (expression has type "Series", - # variable has type "ndarray") - h = Series( # type: ignore[assignment] - h, index=obj.index, dtype="uint64", copy=False - ) + ser = Series(h, index=obj.index, dtype="uint64", copy=False) else: raise TypeError(f"Unexpected type for hashing {type(obj)}") - # error: Incompatible return value type (got "ndarray", expected "Series") - return h # type: ignore[return-value] + + return ser def hash_tuples( @@ -297,15 +286,11 @@ def hash_array( if is_categorical_dtype(dtype): vals = cast("Categorical", vals) return _hash_categorical(vals, encoding, hash_key) - elif is_extension_array_dtype(dtype): - # pandas/core/util/hashing.py:301: error: Item "ndarray" of - # "Union[ExtensionArray, ndarray]" has no attribute "_values_for_factorize" - # [union-attr] - vals, _ = vals._values_for_factorize() # type: ignore[union-attr] - - # error: Argument 1 to "_hash_ndarray" has incompatible type "ExtensionArray"; - # expected "ndarray" - return _hash_ndarray(vals, encoding, hash_key, categorize) # type: ignore[arg-type] + elif not isinstance(vals, np.ndarray): + # i.e. ExtensionArray + vals, _ = vals._values_for_factorize() + + return _hash_ndarray(vals, encoding, hash_key, categorize) def _hash_ndarray(