diff --git a/pandas/core/arrays/string_.py b/pandas/core/arrays/string_.py index 083acf16ec758..c9abef226770c 100644 --- a/pandas/core/arrays/string_.py +++ b/pandas/core/arrays/string_.py @@ -90,8 +90,11 @@ class StringDtype(StorageExtensionDtype): name = "string" - #: StringDtype.na_value uses pandas.NA - na_value = libmissing.NA + #: StringDtype().na_value uses pandas.NA + @property + def na_value(self) -> libmissing.NAType: + return libmissing.NA + _metadata = ("storage",) def __init__(self, storage=None) -> None: @@ -335,13 +338,11 @@ def _from_sequence(cls, scalars, *, dtype: Dtype | None = None, copy=False): na_values = scalars._mask result = scalars._data result = lib.ensure_string_array(result, copy=copy, convert_na_value=False) - result[na_values] = StringDtype.na_value + result[na_values] = libmissing.NA else: - # convert non-na-likes to str, and nan-likes to StringDtype.na_value - result = lib.ensure_string_array( - scalars, na_value=StringDtype.na_value, copy=copy - ) + # convert non-na-likes to str, and nan-likes to StringDtype().na_value + result = lib.ensure_string_array(scalars, na_value=libmissing.NA, copy=copy) # Manually creating new array avoids the validation step in the __init__, so is # faster. Refactor need for validation? @@ -396,7 +397,7 @@ def __setitem__(self, key, value): # validate new items if scalar_value: if isna(value): - value = StringDtype.na_value + value = libmissing.NA elif not isinstance(value, str): raise ValueError( f"Cannot set non-string value '{value}' into a StringArray." @@ -497,7 +498,7 @@ def _cmp_method(self, other, op): if op.__name__ in ops.ARITHMETIC_BINOPS: result = np.empty_like(self._ndarray, dtype="object") - result[mask] = StringDtype.na_value + result[mask] = libmissing.NA result[valid] = op(self._ndarray[valid], other) return StringArray(result) else: @@ -512,7 +513,7 @@ def _cmp_method(self, other, op): # String methods interface # error: Incompatible types in assignment (expression has type "NAType", # base class "PandasArray" defined the type as "float") - _str_na_value = StringDtype.na_value # type: ignore[assignment] + _str_na_value = libmissing.NA # type: ignore[assignment] def _str_map( self, f, na_value=None, dtype: Dtype | None = None, convert: bool = True diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index 3e3df5a3200c1..bb2fefabd6ae5 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -242,8 +242,9 @@ def astype(self, dtype, copy: bool = True): # ------------------------------------------------------------------------ # String methods interface - # error: Cannot determine type of 'na_value' - _str_na_value = StringDtype.na_value # type: ignore[has-type] + # error: Incompatible types in assignment (expression has type "NAType", + # base class "ObjectStringArrayMixin" defined the type as "float") + _str_na_value = libmissing.NA # type: ignore[assignment] def _str_map( self, f, na_value=None, dtype: Dtype | None = None, convert: bool = True diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index 9683c1dd93645..99b2082d409a9 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -676,11 +676,14 @@ class DatetimeTZDtype(PandasExtensionDtype): kind: str_type = "M" num = 101 base = np.dtype("M8[ns]") # TODO: depend on reso? - na_value = NaT _metadata = ("unit", "tz") _match = re.compile(r"(datetime64|M8)\[(?P.+), (?P.+)\]") _cache_dtypes: dict[str_type, PandasExtensionDtype] = {} + @property + def na_value(self) -> NaTType: + return NaT + @cache_readonly def str(self): return f"|M8[{self._unit}]" @@ -1450,7 +1453,9 @@ class BaseMaskedDtype(ExtensionDtype): base = None type: type - na_value = libmissing.NA + @property + def na_value(self) -> libmissing.NAType: + return libmissing.NA @cache_readonly def numpy_dtype(self) -> np.dtype: diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 56fcec751749b..5731d476cef10 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -409,7 +409,10 @@ class Float64Index(NumericIndex): __doc__ = _num_index_shared_docs["class_descr"] % _index_descr_args _typ = "float64index" - _engine_type = libindex.Float64Engine _default_dtype = np.dtype(np.float64) _dtype_validation_metadata = (is_float_dtype, "float") _is_backward_compat_public_numeric_index: bool = False + + @property + def _engine_type(self) -> type[libindex.Float64Engine]: + return libindex.Float64Engine