pandas-dev/pandas · error · NotImplementedError
Default 'empty' implementation is invalid for dtype='{dtype}
Error message
Default 'empty' implementation is invalid for dtype='{dtype}' What it means
Raised by BaseMaskedArray._empty when, after constructing an array filled with dtype._internal_fill_value and an all-True mask, the resulting object either is not an instance of cls or its dtype does not match the requested dtype. This indicates the masked-array subclass has misconfigured its class identity, its dtype property, or its _internal_fill_value, making the default empty() implementation invalid for that dtype.
Source
Thrown at pandas/core/arrays/masked.py:205
return result
@classmethod
def _empty(cls, shape: Shape, dtype: ExtensionDtype) -> Self:
"""
Create an ExtensionArray with the given shape and dtype.
See also
--------
ExtensionDtype.empty
ExtensionDtype.empty is the 'official' public version of this API.
"""
dtype = cast("BaseMaskedDtype", dtype)
values: np.ndarray = np.empty(shape, dtype=dtype.type)
values.fill(dtype._internal_fill_value)
mask = np.ones(shape, dtype=bool)
result = cls(values, mask)
if not isinstance(result, cls) or dtype != result.dtype:
raise NotImplementedError(
f"Default 'empty' implementation is invalid for dtype='{dtype}'"
)
return result
def _formatter(self, boxed: bool = False) -> Callable[[Any], str | None]:
# NEP 51: https://github.com/numpy/numpy/pull/22449
return str
@property
def dtype(self) -> BaseMaskedDtype:
raise AbstractMethodError(self)
@overload
def __getitem__(self, item: ScalarIndexer) -> Any: ...
@overload
def __getitem__(self, item: SequenceIndexer) -> Self: ...
View on GitHub (pinned to 71959b8cb9)
Solutions
- Override _empty (or ExtensionDtype.empty) in the subclass to return a correctly-typed instance.
- Verify dtype.type and dtype._internal_fill_value produce a value compatible with the subclass constructor.
- Ensure cls(values, mask) returns an instance whose .dtype equals the requested dtype.
Example fix
# before
class MyDtype(BaseMaskedDtype):
type = np.float64
_internal_fill_value = 0 # mismatched
# after
class MyArray(BaseMaskedArray):
@classmethod
def _empty(cls, shape, dtype):
values = np.empty(shape, dtype=dtype.type)
values.fill(dtype._internal_fill_value)
return cls(values, np.ones(shape, dtype=bool)) Defensive patterns
Strategy: validation
Validate before calling
def empty_works(dtype, shape):
arr = dtype.empty(shape)
return isinstance(arr, type(arr)) and arr.dtype == dtype Type guard
def subclass_consistent(cls, dtype) -> bool:
try:
a = cls._empty((1,), dtype)
return isinstance(a, cls) and a.dtype == dtype
except Exception:
return False Prevention
- Override _empty/empty in custom BaseMaskedArray subclasses.
- Keep dtype.type, _internal_fill_value, and the constructor in sync.
- Add a unit test that calls ExtensionDtype.empty on every registered dtype.
When it happens
Trigger: Authoring a custom ExtensionDtype/ExtensionArray subclass of BaseMaskedArray where dtype.type, _internal_fill_value, or the constructor don't line up; calling ExtensionDtype.empty(shape) on such a dtype.
Common situations: Library authors extending pandas masked arrays; mis-set class attributes after a refactor or dtype rename.
Related errors
- No masked accumulation defined for dtype {values.dtype.type}
- Invalid value '{value!s}' for dtype '{self.dtype}'
- interpolate is not implemented for dtype={self.dtype}
- The numba engine only supports using string or numeric colum
- You cannot access the property {name}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/3f2dc4d8855ff9e5.
Report an issue: GitHub.