Skip to content

Fix typing for extension arrays and extension dtypes without isin and astype #40421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f2c52a4
small typing fixes
Dr-Irv Jan 23, 2021
d7ff8d3
fix ExtensionArray and EXtensionDtype
Dr-Irv Jan 23, 2021
49fa06e
merge with master
Dr-Irv Jan 31, 2021
03b2c4a
fixes for delete, isin, unique
Dr-Irv Jan 31, 2021
3e19958
fix import of Literal
Dr-Irv Jan 31, 2021
6861901
remove quotes on ExtensionDType.construct_from_string
Dr-Irv Jan 31, 2021
9be6486
move numpy workaround to _typing.py
Dr-Irv Feb 1, 2021
260b367
remove numpy dummy
Dr-Irv Feb 2, 2021
6276725
remove extra line in _typing
Dr-Irv Feb 2, 2021
4dafaca
Merge remote-tracking branch 'upstream/master' into extensiontyping
Dr-Irv Feb 3, 2021
8b2cee2
import Literal
Dr-Irv Feb 3, 2021
3a7d839
Merge remote-tracking branch 'upstream/master' into extensiontyping
Dr-Irv Feb 14, 2021
a21bb60
merge with master
Dr-Irv Mar 8, 2021
8cd6b76
isort precommit fix
Dr-Irv Mar 8, 2021
e0e0131
fix interval.repeat() typing
Dr-Irv Mar 8, 2021
6a6a21f
overload for __getitem__ and use pattern with ExtensionArrayT as self…
Dr-Irv Mar 9, 2021
bf753e6
lose less ExtensionArrayT. Make registry private. consolidate overload
Dr-Irv Mar 10, 2021
c9795a5
remove ExtensionArray typing of self
Dr-Irv Mar 10, 2021
d452842
Merge remote-tracking branch 'upstream/master' into extensiontyping
Dr-Irv Mar 10, 2021
3c2c78b
merge with upstream/master
Dr-Irv Mar 12, 2021
548c198
make extension arrays work with new typing, fixing astype and to_numpy
Dr-Irv Mar 12, 2021
db8ed9b
fix Literal import
Dr-Irv Mar 12, 2021
f8191f8
fix logic in ensure_int_or_float
Dr-Irv Mar 12, 2021
575645f
fix conflict with master
Dr-Irv Mar 12, 2021
6f8fcb5
fix typing in groupby to_numpy call
Dr-Irv Mar 12, 2021
3ea2420
fix groupby again. Allow kwargs for extension to_numpy
Dr-Irv Mar 13, 2021
c83a628
Merge remote-tracking branch 'upstream/master' into extensiontyping
simonjayhawkins Mar 13, 2021
5bb24d4
fixes for merge with master
Dr-Irv Mar 13, 2021
ad1ab3b
remove astype and isin changes
Dr-Irv Mar 13, 2021
63c3d6d
add comment to cast in managers. change return type of astype
Dr-Irv Mar 13, 2021
1882074
add 0 as argument for repeat`
Dr-Irv Mar 13, 2021
1274a76
remove kwargs from to_numpy
Dr-Irv Mar 13, 2021
363e203
remove more kwargs from to_numpy calls
Dr-Irv Mar 13, 2021
01c942c
Merge remote-tracking branch 'upstream/master' into limitextensiontyping
Dr-Irv Mar 13, 2021
1196132
don't cast in astype. TODO for overload of astype
Dr-Irv Mar 13, 2021
66d5da4
remove private registry, getitem overloads, typevar on DateTimeScalar
Dr-Irv Mar 13, 2021
5411998
Remove List[Any] from getitem
Dr-Irv Mar 13, 2021
9b7481d
remove spacing change in _mixins.py and __getitem__
Dr-Irv Mar 13, 2021
4bd3422
remove cast in io/formats. Change isinstance check in pandas.core.ba…
Dr-Irv Mar 14, 2021
3b1ff79
merge with master to resolve conflicts
Dr-Irv Mar 14, 2021
5719daa
merge with master, remove more ignores
Dr-Irv Apr 3, 2021
dbfb3a2
remove mypy comments from format
Dr-Irv Apr 3, 2021
d41bf91
resolve conflicts with master
Dr-Irv Apr 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,11 @@ def isin(comps: AnyArrayLike, values: AnyArrayLike) -> np.ndarray:
comps = _ensure_arraylike(comps)
comps = extract_array(comps, extract_numpy=True)
if is_extension_array_dtype(comps.dtype):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just make this an isinstance(comps, ExtensionArray):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't do that. Creates a circular import.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could do if not isinstance(comps, np.ndarray). after the extract_array call comps should be ArrayLike.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. But I think I will do that in another PR related to fixing args for isin

# error: Incompatible return value type (got "Series", expected "ndarray")
# error: Item "ndarray" of "Union[Any, ndarray]" has no attribute "isin"
return comps.isin(values) # type: ignore[return-value,union-attr]
# error: Argument 1 to "isin" of "ExtensionArray" has incompatible type
# "Union[Any, ExtensionArray, ndarray]"; expected "Sequence[Any]"
# error: Item "ndarray" of "Union[Any, ExtensionArray, ndarray]" has no
# attribute "isin"
return comps.isin(values) # type: ignore[arg-type, union-attr]

elif needs_i8_conversion(comps.dtype):
# Dispatch to DatetimeLikeArrayMixin.isin
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/array_algos/putmask.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def extract_bool_array(mask: ArrayLike) -> np.ndarray:
# We could have BooleanArray, Sparse[bool], ...
# Except for BooleanArray, this is equivalent to just
# np.asarray(mask, dtype=bool)
mask = mask.to_numpy(dtype=bool, na_value=False)
mask = mask.to_numpy(dtype=np.dtype(bool), na_value=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't need to be changed. i've opened #41185 as a precursor to fix these false positives.


mask = np.asarray(mask, dtype=bool)
return mask
Expand Down
86 changes: 53 additions & 33 deletions pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
TYPE_CHECKING,
Any,
Callable,
Iterator,
Sequence,
TypeVar,
cast,
Expand All @@ -24,6 +25,7 @@
from pandas._typing import (
ArrayLike,
Dtype,
NpDtype,
PositionalIndexer,
Shape,
)
Expand Down Expand Up @@ -69,6 +71,7 @@
)

if TYPE_CHECKING:
from typing import Literal

class ExtensionArraySupportsAnyAll("ExtensionArray"):
def any(self, *, skipna: bool = True) -> bool:
Expand Down Expand Up @@ -375,7 +378,7 @@ def __len__(self) -> int:
"""
raise AbstractMethodError(self)

def __iter__(self):
def __iter__(self) -> Iterator[Any]:
"""
Iterate over elements of the array.
"""
Expand Down Expand Up @@ -424,9 +427,9 @@ def __ne__(self, other: Any) -> ArrayLike: # type: ignore[override]

def to_numpy(
self,
dtype: Dtype | None = None,
dtype: NpDtype | None = None,
copy: bool = False,
na_value=lib.no_default,
na_value: Any | None = lib.no_default,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None seems redundant here.

) -> np.ndarray:
"""
Convert to a NumPy ndarray.
Expand All @@ -453,12 +456,7 @@ def to_numpy(
-------
numpy.ndarray
"""
# error: Argument "dtype" to "asarray" has incompatible type
# "Union[ExtensionDtype, str, dtype[Any], Type[str], Type[float], Type[int],
# Type[complex], Type[bool], Type[object], 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]]]"
result = np.asarray(self, dtype=dtype) # type: ignore[arg-type]
result = np.asarray(self, dtype=dtype)
if copy or na_value is not lib.no_default:
result = result.copy()
if na_value is not lib.no_default:
Expand Down Expand Up @@ -510,8 +508,7 @@ def nbytes(self) -> int:
# ------------------------------------------------------------------------
# Additional Methods
# ------------------------------------------------------------------------

def astype(self, dtype, copy=True):
def astype(self, dtype: Dtype, copy: bool = True):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when adding types, we should ensure that the types match the docstrings. From the PR title and previous discussion, IIUC astype was being done separately.

I would revert this for now until this method is sorted properly.

see also #41018 (comment) and response.

The docstring states we return np.ndarray and the one-liner suggests that too. We sometimes also return an ExtensionArray, this is dependent on the type of dtype.

my concern is that if we add the type now, this may get forgotten.

"""
Cast to a NumPy array with 'dtype'.

Expand Down Expand Up @@ -544,8 +541,11 @@ def astype(self, dtype, copy=True):
dtype, (ArrowStringDtype, StringDtype)
): # allow conversion to StringArrays
return dtype.construct_array_type()._from_sequence(self, copy=False)

return np.array(self, dtype=dtype, copy=copy)
# error: Argument "dtype" to "array" has incompatible type
# "Union[ExtensionDtype, dtype[Any]]"; expected "Union[dtype[Any], None,
# type, _SupportsDType, str, Union[Tuple[Any, int], Tuple[Any,
# Union[int, Sequence[int]]], List[Any], _DTypeDict, Tuple[Any, Any]]]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just assert that this is a NpDtype here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to address astype() (where the above code is) in a later PR. That will remove the above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see previous comment, remove the added type and this ignore will not be needed yet.

return np.array(self, dtype=dtype, copy=copy) # type: ignore[arg-type]

def isna(self) -> np.ndarray | ExtensionArraySupportsAnyAll:
"""
Expand Down Expand Up @@ -591,8 +591,8 @@ def argsort(
ascending: bool = True,
kind: str = "quicksort",
na_position: str = "last",
*args,
**kwargs,
*args: Any,
**kwargs: Any,
Comment on lines +594 to +595
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave these untyped for now.

These are passed through to numpy.argsort, so we should be able to be more precise.

try to avoid adding Any where we maybe able to more precise with further investigation.

side note: these actually don't seem to be passed in the base implementation.

) -> np.ndarray:
"""
Return the indices that would sort this array.
Expand Down Expand Up @@ -680,7 +680,12 @@ def argmax(self, skipna: bool = True) -> int:
raise NotImplementedError
return nargminmax(self, "argmax")

def fillna(self, value=None, method=None, limit=None):
def fillna(
self,
value: Any | ArrayLike | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the ArrayLike (and None) redundant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. We want to indicate that you can provide a single value (but for an ExtensionArray that could be of the type of values stored in the array), or an array that indicates specific values to put where there are NA values.

method: Literal["backfill", "bfill", "ffill", "pad"] | None = None,
limit: int | None = None,
) -> ExtensionArray:
"""
Fill NA/NaN values using the specified method.

Expand Down Expand Up @@ -729,16 +734,19 @@ def fillna(self, value=None, method=None, limit=None):
new_values = self.copy()
return new_values

def dropna(self):
def dropna(self) -> ExtensionArrayT:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the typevar is not bound to anything. dropna returns same type as self

Suggested change
def dropna(self) -> ExtensionArrayT:
def dropna(self: ExtensionArrayT) -> ExtensionArrayT:

"""
Return ExtensionArray without NA values.

Returns
-------
valid : ExtensionArray
"""
# error: Unsupported operand type for ~ ("ExtensionArray")
return self[~self.isna()] # type: ignore[operator]
# error: Incompatible return value type (got "Union[ExtensionArray, Any]",
# expected "ExtensionArrayT")
# error: Unsupported operand type for ~ ("Union[ndarray,
# ExtensionArraySupportsAnyAll]")
return self[~self.isna()] # type: ignore[return-value, operator]

def shift(self, periods: int = 1, fill_value: object = None) -> ExtensionArray:
"""
Expand Down Expand Up @@ -794,7 +802,7 @@ def shift(self, periods: int = 1, fill_value: object = None) -> ExtensionArray:
b = empty
return self._concat_same_type([a, b])

def unique(self):
def unique(self) -> ExtensionArray:
"""
Compute the ExtensionArray of unique values.

Expand All @@ -805,7 +813,12 @@ def unique(self):
uniques = unique(self.astype(object))
return self._from_sequence(uniques, dtype=self.dtype)

def searchsorted(self, value, side="left", sorter=None):
def searchsorted(
self,
value: Sequence[Any],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sequence is not yet compatible with EA (and others). see #28770

side: Literal["left", "right"] = "left",
sorter: Sequence[Any] | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from the docstring sorter is an arraylike of ints.

) -> np.ndarray:
"""
Find indices where elements should be inserted to maintain order.

Expand Down Expand Up @@ -850,7 +863,8 @@ def searchsorted(self, value, side="left", sorter=None):
# 1. Values outside the range of the `data_for_sorting` fixture
# 2. Values between the values in the `data_for_sorting` fixture
# 3. Missing values.
arr = self.astype(object)
# TODO: overload astype so that cast is unnecessary
arr = cast(np.ndarray, self.astype(object))
return arr.searchsorted(value, side=side, sorter=sorter)

def equals(self, other: object) -> bool:
Expand Down Expand Up @@ -887,7 +901,7 @@ def equals(self, other: object) -> bool:
equal_na = self.isna() & other.isna() # type: ignore[operator]
return bool((equal_values | equal_na).all())

def isin(self, values) -> np.ndarray:
def isin(self, values: Sequence[Any]) -> np.ndarray:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above. also need to accept Arraylike.

"""
Pointwise comparison for set containment in the given values.

Expand All @@ -901,7 +915,9 @@ def isin(self, values) -> np.ndarray:
-------
np.ndarray[bool]
"""
return isin(np.asarray(self), values)
# error: Argument 2 to "isin" has incompatible type "Sequence[Any]"; expected
# "Union[Union[ExtensionArray, ndarray], Index, Series]"
return isin(self.astype(object), values) # type: ignore[arg-type]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you avoid adding this ignore. i.e. make the types of EA.isin and algos.isin consistent.


def _values_for_factorize(self) -> tuple[np.ndarray, Any]:
"""
Expand All @@ -925,7 +941,7 @@ def _values_for_factorize(self) -> tuple[np.ndarray, Any]:
The values returned by this method are also used in
:func:`pandas.util.hash_pandas_object`.
"""
return self.astype(object), np.nan
return cast(np.ndarray, self.astype(object)), np.nan
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should type astype as a precursor to avoid this and other cast.

It's also a blocker for #41018

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So are you suggesting that I do a PR for astype() changes first? I thought we agreed that we would do it after this one. I can make a note to remove the cast when astype is done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessarily. This is a big PR. break it down to small chunks and we can maybe do some in parallel. not adverse to a PR per method. much more likely to get input/review from others and a discussion going with smaller PRs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PRs without casts or ignores should sail through.. well maybe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll put this PR in draft status. Too many issues with respect to calling numpy things that you are attempting to deal with elsewhere. I'll try some smaller ones.


def factorize(self, na_sentinel: int = -1) -> tuple[np.ndarray, ExtensionArray]:
"""
Expand Down Expand Up @@ -1023,7 +1039,11 @@ def factorize(self, na_sentinel: int = -1) -> tuple[np.ndarray, ExtensionArray]:

@Substitution(klass="ExtensionArray")
@Appender(_extension_array_shared_docs["repeat"])
def repeat(self, repeats, axis=None):
def repeat(
self,
repeats: int | Sequence[int],
axis: Literal[None, 0] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not seen Literal[None] used b4.

) -> ExtensionArray:
nv.validate_repeat((), {"axis": axis})
ind = np.arange(len(self)).repeat(repeats)
return self.take(ind)
Expand All @@ -1033,12 +1053,12 @@ def repeat(self, repeats, axis=None):
# ------------------------------------------------------------------------

def take(
self: ExtensionArrayT,
self,
indices: Sequence[int],
*,
allow_fill: bool = False,
fill_value: Any = None,
) -> ExtensionArrayT:
) -> ExtensionArray:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert this change.

"""
Take elements from an array.

Expand Down Expand Up @@ -1127,7 +1147,7 @@ def take(self, indices, allow_fill=False, fill_value=None):
# pandas.api.extensions.take
raise AbstractMethodError(self)

def copy(self: ExtensionArrayT) -> ExtensionArrayT:
def copy(self) -> ExtensionArray:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this

"""
Return a copy of the array.

Expand Down Expand Up @@ -1207,7 +1227,7 @@ def _formatter(self, boxed: bool = False) -> Callable[[Any], str | None]:
# Reshaping
# ------------------------------------------------------------------------

def transpose(self, *axes) -> ExtensionArray:
def transpose(self, *axes: int) -> ExtensionArray:
"""
Return a transposed view on this array.

Expand All @@ -1220,7 +1240,7 @@ def transpose(self, *axes) -> ExtensionArray:
def T(self) -> ExtensionArray:
return self.transpose()

def ravel(self, order="C") -> ExtensionArray:
def ravel(self, order: Literal["C", "F", "A", "K"] | None = "C") -> ExtensionArray:
"""
Return a flattened view on this array.

Expand Down Expand Up @@ -1294,13 +1314,13 @@ def _reduce(self, name: str, *, skipna: bool = True, **kwargs):
"""
raise TypeError(f"cannot perform {name} with type {self.dtype}")

def __hash__(self):
def __hash__(self) -> int:
raise TypeError(f"unhashable type: {repr(type(self).__name__)}")

# ------------------------------------------------------------------------
# Non-Optimized Default Methods

def delete(self: ExtensionArrayT, loc) -> ExtensionArrayT:
def delete(self, loc: int | Sequence[int]) -> ExtensionArray:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert the typevar change.

indexer = np.delete(np.arange(len(self)), loc)
return self.take(indexer)

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/boolean.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def reconstruct(x):
def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
return coerce_to_array(value)

def astype(self, dtype, copy: bool = True) -> ArrayLike:
def astype(self, dtype: Dtype, copy: bool = True) -> ArrayLike:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

astype changes are going to be a separate PR. revert for now

"""
Cast to a NumPy array or ExtensionArray with 'dtype'.

Expand Down
3 changes: 2 additions & 1 deletion pandas/core/arrays/floating.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
)
from pandas._typing import (
ArrayLike,
Dtype,
DtypeObj,
)
from pandas.compat.numpy import function as nv
Expand Down Expand Up @@ -271,7 +272,7 @@ def _from_sequence_of_strings(
def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
return coerce_to_array(value, dtype=self.dtype)

def astype(self, dtype, copy: bool = True) -> ArrayLike:
def astype(self, dtype: Dtype, copy: bool = True) -> ArrayLike:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

"""
Cast to a NumPy array or ExtensionArray with 'dtype'.

Expand Down
4 changes: 3 additions & 1 deletion pandas/core/arrays/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,9 @@ def delete(self: IntervalArrayT, loc) -> IntervalArrayT:
return self._shallow_copy(left=new_left, right=new_right)

@Appender(_extension_array_shared_docs["repeat"] % _shared_docs_kwargs)
def repeat(self: IntervalArrayT, repeats: int, axis=None) -> IntervalArrayT:
def repeat(
self: IntervalArrayT, repeats: int | Sequence[int], axis=None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this compatible with numpy where the type is int or array of ints?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compatible in what sense? numpy takes a superset of Sequence[int] as the repeats argument. Ideally, we'd use the numpy argtype for repeats throughout, but we can't depend on numpy 1.20 being available

) -> IntervalArrayT:
nv.validate_repeat((), {"axis": axis})
left_repeat = self.left.repeat(repeats)
right_repeat = self.right.repeat(repeats)
Expand Down
5 changes: 1 addition & 4 deletions pandas/core/arrays/masked.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,7 @@ def __len__(self) -> int:
def __invert__(self: BaseMaskedArrayT) -> BaseMaskedArrayT:
return type(self)(~self._data, self._mask.copy())

# error: Argument 1 of "to_numpy" is incompatible with supertype "ExtensionArray";
# supertype defines the argument type as "Union[ExtensionDtype, str, dtype[Any],
# Type[str], Type[float], Type[int], Type[complex], Type[bool], Type[object], None]"
def to_numpy( # type: ignore[override]
def to_numpy(
self,
dtype: NpDtype | None = None,
copy: bool = False,
Expand Down
5 changes: 1 addition & 4 deletions pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,7 @@ def skew(
# ------------------------------------------------------------------------
# Additional Methods

# error: Argument 1 of "to_numpy" is incompatible with supertype "ExtensionArray";
# supertype defines the argument type as "Union[ExtensionDtype, str, dtype[Any],
# Type[str], Type[float], Type[int], Type[complex], Type[bool], Type[object], None]"
def to_numpy( # type: ignore[override]
def to_numpy(
self,
dtype: NpDtype | None = None,
copy: bool = False,
Expand Down
13 changes: 5 additions & 8 deletions pandas/core/arrays/string_arrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
missing as libmissing,
)
from pandas._typing import (
Dtype,
DtypeArg,
NpDtype,
PositionalIndexer,
type_t,
Expand Down Expand Up @@ -227,15 +227,15 @@ def _chk_pyarrow_available(cls) -> None:
raise ImportError(msg)

@classmethod
def _from_sequence(cls, scalars, dtype: Dtype | None = None, copy: bool = False):
def _from_sequence(cls, scalars, dtype: DtypeArg | None = None, copy: bool = False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DtypeArg?

cls._chk_pyarrow_available()
# convert non-na-likes to str, and nan-likes to ArrowStringDtype.na_value
scalars = lib.ensure_string_array(scalars, copy=False)
return cls(pa.array(scalars, type=pa.string(), from_pandas=True))

@classmethod
def _from_sequence_of_strings(
cls, strings, dtype: Dtype | None = None, copy: bool = False
cls, strings, dtype: DtypeArg | None = None, copy: bool = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

):
return cls._from_sequence(strings, dtype=dtype, copy=copy)

Expand All @@ -254,10 +254,7 @@ def __arrow_array__(self, type=None):
"""Convert myself to a pyarrow Array or ChunkedArray."""
return self._data

# error: Argument 1 of "to_numpy" is incompatible with supertype "ExtensionArray";
# supertype defines the argument type as "Union[ExtensionDtype, str, dtype[Any],
# Type[str], Type[float], Type[int], Type[complex], Type[bool], Type[object], None]"
def to_numpy( # type: ignore[override]
def to_numpy(
self,
dtype: NpDtype | None = None,
copy: bool = False,
Expand Down Expand Up @@ -696,7 +693,7 @@ def value_counts(self, dropna: bool = True) -> Series:

_str_na_value = ArrowStringDtype.na_value

def _str_map(self, f, na_value=None, dtype: Dtype | None = None):
def _str_map(self, f, na_value=None, dtype: DtypeArg | None = None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

# TODO: de-duplicate with StringArray method. This method is moreless copy and
# paste.

Expand Down
Loading