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

ExtensionArray._empty (base.py:2862) constructs an empty array via _from_sequence + take(-1, allow_fill=True) and validates the round-trip preserves type and dtype; if it does not, it raises NotImplementedError. This guards internal callers (e.g. dtype.empty) from silently producing a wrong-typed array, and is primarily an ExtensionArray-author contract violation.

Source

Thrown at pandas/core/arrays/base.py:2862

    @classmethod
    def _empty(cls, shape: Shape, dtype: ExtensionDtype):
        """
        Create an ExtensionArray with the given shape and dtype.

        See also
        --------
        ExtensionDtype.empty
            ExtensionDtype.empty is the 'official' public version of this API.
        """
        # Implementer note: while ExtensionDtype.empty is the public way to
        # call this method, it is still required to implement this `_empty`
        # method as well (it is called internally in pandas)
        obj = cls._from_sequence([], dtype=dtype)

        taker = np.broadcast_to(np.intp(-1), shape)
        result = obj.take(taker, allow_fill=True)
        if not isinstance(result, cls) or dtype != result.dtype:
            raise NotImplementedError(
                f"Default 'empty' implementation is invalid for dtype='{dtype}'"
            )
        return result

    def _quantile(self, qs: npt.NDArray[np.float64], interpolation: str) -> Self:
        """
        Compute the quantiles of self for each quantile in `qs`.

        Parameters
        ----------
        qs : np.ndarray[float64]
        interpolation: str

        Returns
        -------
        same type as self
        """
        mask = np.asarray(self.isna())

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Override _empty(cls, shape, dtype) in your ExtensionArray subclass to return a correctly-typed empty array.
  2. Fix take(allow_fill=True) so a -1 indexer yields NA of the correct dtype.
  3. Fix _from_sequence to return an instance of cls with the requested dtype.
  4. Report to the third-party EA library if you are not the author.

Example fix

# before: custom EA whose take() returns wrong type
# raises 'Default empty implementation is invalid'

# after
@classmethod
def _empty(cls, shape, dtype):
    obj = cls._from_sequence([], dtype=dtype)
    taker = np.broadcast_to(np.intp(-1), shape)
    return obj.take(taker, allow_fill=True)
Defensive patterns

Strategy: validation

Validate before calling

def verify_empty_roundtrip(cls, dtype):
    obj = cls._from_sequence([], dtype=dtype)
    taker = __import__("numpy").broadcast_to(__import__("numpy").intp(-1), (3,))
    result = obj.take(taker, allow_fill=True)
    return isinstance(result, cls) and result.dtype == dtype

Type guard

def ea_roundtrips_empty(cls, dtype) -> bool:
    try:
        verify_empty_roundtrip(cls, dtype)
        return True
    except Exception:
        return False

Try / catch

try:
    arr = dtype.empty(shape, dtype)
except NotImplementedError as e:
    if "empty" in str(e):
        # fall back to building element-wise
        arr = dtype.construct_array_type()._from_sequence([dtype.na_value] * int(__import__("numpy").prod(shape)))
    else:
        raise

Prevention

When it happens

Trigger: Triggered when pandas internally calls ExtensionDtype.empty(shape, dtype) (which delegates to _empty) for an EA whose _from_sequence or take does not round-trip a sentinel correctly. Common during reshaping/groupby/concat on a custom EA.

Common situations: Third-party or custom ExtensionArray with a buggy _from_sequence or take(allow_fill=True) implementation; changes after a pandas upgrade tighten the round-trip check.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/2acfc0ae6e77c508. Report an issue: GitHub.