{"record":{"id":"bbbdb6459915b04c","repo":"pandas-dev/pandas","slug":"mask-should-be-boolean-numpy-array-use-the-pd-ar","errorCode":null,"errorMessage":"mask should be boolean numpy array. Use the 'pd.array' function instead","messagePattern":"mask should be boolean numpy array\\. Use the 'pd\\.array' function instead","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":154,"sourceCode":"    \"\"\"\n\n    # our underlying data and mask are each ndarrays\n    _data: np.ndarray\n    _mask: npt.NDArray[np.bool_]\n\n    @classmethod\n    def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self:\n        result = BaseMaskedArray.__new__(cls)\n        result._data = values\n        result._mask = mask\n        return result\n\n    def __init__(\n        self, values: np.ndarray, mask: npt.NDArray[np.bool_], copy: bool = False\n    ) -> None:\n        # values is supposed to already be validated in the subclass\n        if not (isinstance(mask, np.ndarray) and mask.dtype == np.bool_):\n            raise TypeError(\n                \"mask should be boolean numpy array. Use \"\n                \"the 'pd.array' function instead\"\n            )\n        if values.shape != mask.shape:\n            raise ValueError(\"values.shape must match mask.shape\")\n\n        if copy:\n            values = values.copy()\n            mask = mask.copy()\n\n        self._data = values\n        self._mask = mask\n\n    @classmethod\n    def _from_sequence(cls, scalars, *, dtype=None, copy: bool = False) -> Self:\n        values, mask = cls._coerce_to_array(scalars, dtype=dtype, copy=copy)\n        return cls(values, mask)\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/masked.py#L136-L172","documentation":"Raised in BaseMaskedArray.__init__ when 'mask' is not a numpy ndarray of dtype bool. The constructor is internal API; users should construct masked arrays (IntegerArray, BooleanArray, FloatingArray, etc.) via pd.array(...) which coerces inputs correctly.","triggerScenarios":"pd.arrays.IntegerArray(values, [True, False]) (list mask); SomeMaskedArray(values, np.array([1, 0])) (non-bool dtype); direct subclass construction with a Python list mask.","commonSituations":"Direct construction by users or extension authors bypassing pd.array; passing Python lists/tuples as masks; passing integer 0/1 masks.","solutions":["Use pd.array(values, dtype='Int64') (or the appropriate masked dtype) for public construction.","If extending BaseMaskedArray, convert the mask with np.asarray(mask, dtype=bool) before calling super().__init__."],"exampleFix":"// before\npd.arrays.IntegerArray(values, [True, False, True])\n// after\npd.array(values, dtype='Int64')","handlingStrategy":"type-guard","validationCode":"import numpy as np\n\ndef coerce_mask(mask):\n    m = np.asarray(mask)\n    if m.dtype != np.bool_:\n        m = m.astype(bool)\n    return m","typeGuard":"import numpy as np\n\ndef is_bool_ndarray(m):\n    return isinstance(m, np.ndarray) and m.dtype == np.bool_","tryCatchPattern":null,"preventionTips":["Use pd.array(values, dtype=...) for public construction of masked arrays.","Subclass authors: convert the mask to np.bool_ in __init__ before super().","Never pass Python lists or integer 0/1 arrays as the mask directly."],"tags":["masked-array","constructor","internal-api"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}