{"record":{"id":"3f2dc4d8855ff9e5","repo":"pandas-dev/pandas","slug":"default-empty-implementation-is-invalid-for-dtyp-3f2dc4","errorCode":null,"errorMessage":"Default 'empty' implementation is invalid for dtype='{dtype}'","messagePattern":"Default 'empty' implementation is invalid for dtype='(.+?)'","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":205,"sourceCode":"        return result\n\n    @classmethod\n    def _empty(cls, shape: Shape, dtype: ExtensionDtype) -> Self:\n        \"\"\"\n        Create an ExtensionArray with the given shape and dtype.\n\n        See also\n        --------\n        ExtensionDtype.empty\n            ExtensionDtype.empty is the 'official' public version of this API.\n        \"\"\"\n        dtype = cast(\"BaseMaskedDtype\", dtype)\n        values: np.ndarray = np.empty(shape, dtype=dtype.type)\n        values.fill(dtype._internal_fill_value)\n        mask = np.ones(shape, dtype=bool)\n        result = cls(values, mask)\n        if not isinstance(result, cls) or dtype != result.dtype:\n            raise NotImplementedError(\n                f\"Default 'empty' implementation is invalid for dtype='{dtype}'\"\n            )\n        return result\n\n    def _formatter(self, boxed: bool = False) -> Callable[[Any], str | None]:\n        # NEP 51: https://github.com/numpy/numpy/pull/22449\n        return str\n\n    @property\n    def dtype(self) -> BaseMaskedDtype:\n        raise AbstractMethodError(self)\n\n    @overload\n    def __getitem__(self, item: ScalarIndexer) -> Any: ...\n\n    @overload\n    def __getitem__(self, item: SequenceIndexer) -> Self: ...\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/masked.py#L187-L223","documentation":"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.","triggerScenarios":"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.","commonSituations":"Third-party pandas extension subtypes of BaseMaskedArray; upgrading pandas where the empty contract tightened; subclass authors who override dtype/constructors.","solutions":["If you are a subclass author: override _empty / __new__ so that cls(values, mask).dtype == dtype for the requested dtype.","If you are a user: use the canonical pandas masked dtype (Int64, Float64, boolean, string) instead of a custom subclass.","Patch the subclass so constructing from a fill-value array yields the requested dtype exactly."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def safe_empty(dtype, shape):\n    arr = dtype.empty(shape)\n    if arr.dtype != dtype:\n        raise TypeError(f'empty produced {arr.dtype}, expected {dtype}')\n    return arr","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Subclass authors: ensure cls(values, mask).dtype == dtype in _empty.","Users: prefer canonical pandas masked dtypes over custom subclasses.","After pandas upgrades, re-test custom BaseMaskedArray subclasses' empty/dtype contract."],"tags":["masked-array","subclass","internal-api","empty"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}