Skip to content

API: EA._can_hold_na -> EDtype.can_hold_na #41654

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

Merged
merged 11 commits into from
Jun 8, 2021
5 changes: 4 additions & 1 deletion pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
from pandas.util._decorators import (
Appender,
Substitution,
cache_readonly,
)
from pandas.util._validators import (
validate_bool_kwarg,
@@ -1273,7 +1274,9 @@ def _concat_same_type(
# such as take(), reindex(), shift(), etc. In addition, those results
# will then be of the ExtensionArray subclass rather than an array
# of objects
_can_hold_na = True
@cache_readonly
def _can_hold_na(self) -> bool:
return self.dtype._can_hold_na

def _reduce(self, name: str, *, skipna: bool = True, **kwargs):
"""
1 change: 0 additions & 1 deletion pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
@@ -353,7 +353,6 @@ class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMi
# tolist is not actually deprecated, just suppressed in the __dir__
_hidden_attrs = PandasObject._hidden_attrs | frozenset(["tolist"])
_typ = "categorical"
_can_hold_na = True

_dtype: CategoricalDtype

4 changes: 4 additions & 0 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
@@ -159,6 +159,10 @@ class DatetimeLikeArrayMixin(OpsMixin, NDArrayBackedExtensionArray):
_recognized_scalars: tuple[type, ...]
_ndarray: np.ndarray

@cache_readonly
def _can_hold_na(self) -> bool:
return True

def __init__(self, data, dtype: Dtype | None = None, freq=None, copy=False):
raise AbstractMethodError(self)

7 changes: 7 additions & 0 deletions pandas/core/dtypes/base.py
Original file line number Diff line number Diff line change
@@ -367,6 +367,13 @@ def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None:
else:
return None

@property
def _can_hold_na(self) -> bool:
"""
Can arrays of this dtype hold NA values?
"""
return True


def register_extension_dtype(cls: type[E]) -> type[E]:
"""
10 changes: 5 additions & 5 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
@@ -175,15 +175,15 @@ def is_view(self) -> bool:
return values.base is not None

@final
@property
@cache_readonly
def _can_hold_na(self) -> bool:
"""
Can we store NA values in this Block?
"""
values = self.values
if isinstance(values, np.ndarray):
return values.dtype.kind not in ["b", "i", "u"]
return values._can_hold_na
dtype = self.dtype
if isinstance(dtype, np.dtype):
return dtype.kind not in ["b", "i", "u"]
return dtype._can_hold_na

@final
@cache_readonly
8 changes: 5 additions & 3 deletions pandas/tests/extension/test_external_block.py
Original file line number Diff line number Diff line change
@@ -14,9 +14,11 @@
class CustomBlock(ExtensionBlock):

_holder = np.ndarray
# error: Cannot override final attribute "_can_hold_na"
# (previously declared in base class "Block")
_can_hold_na = False # type: ignore[misc]

# Cannot override final attribute "_can_hold_na"
@property # type: ignore[misc]
def _can_hold_na(self) -> bool:
return False


@pytest.fixture