pandas-dev/pandas · error · NotImplementedError

Default 'empty' implementation is invalid for dtype=

Error message

Default 'empty' implementation is invalid for dtype='{dtype}'

What it means

Raised in BaseMaskedArray._empty when the default empty-implementation produces a result whose type or dtype does not match the requested dtype. This signals a subclass contract violation (a subclass overrides __new__/dtype in a way that breaks the default _empty) rather than a user error. The check exists so a broken subclass fails loudly instead of returning wrong-typed data.

Solutions

  1. If you are a subclass author: override _empty / __new__ so that cls(values, mask).dtype == dtype for the requested dtype.
  2. If you are a user: use the canonical pandas masked dtype (Int64, Float64, boolean, string) instead of a custom subclass.
  3. Patch the subclass so constructing from a fill-value array yields the requested dtype exactly.
Defensive patterns

Strategy: validation

Validate before calling

def safe_empty(dtype, shape):
    arr = dtype.empty(shape)
    if arr.dtype != dtype:
        raise TypeError(f'empty produced {arr.dtype}, expected {dtype}')
    return arr

Prevention

When it happens

Trigger: Calling dtype.empty(shape) on a misimplemented BaseMaskedArray subclass; creating arrays via a third-party extension subtype whose constructor does not honor the requested dtype; pandas internal changes after upgrades exposing a latent subclass bug.

Common situations: Third-party pandas extension subtypes of BaseMaskedArray; upgrading pandas where the empty contract tightened; subclass authors who override dtype/constructors.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/3f2dc4d8855ff9e5. Report an issue: GitHub.

Appendix: 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 3b7651241d)