pandas-dev/pandas · error · NotImplementedError

operator ' ' not implemented for bool dtypes

Error message

operator '{op_name}' not implemented for bool dtypes

What it means

Raised by BaseMaskedArray arithmetic when self.dtype.kind is 'b' (nullable boolean) and the operation is one of floordiv, rfloordiv, pow, rpow, truediv, rtruediv. These operators are mathematically undefined for booleans in pandas' masked-array path, so it raises NotImplementedError to match non-masked Series behavior (GH#41165).

Solutions

  1. Cast to an integer dtype before the op: bool_arr.astype('Int8') // 2.
  2. Use a nullable numeric dtype for the column from the start if math is intended.
  3. Refactor the operation to a form defined for booleans (e.g. & / | / ~).

Example fix

// before
bool_arr = pd.array([True, False], dtype='boolean')
bool_arr ** 2   # raises
// after
bool_arr.astype('Int8') ** 2
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
bool_ops = {'floordiv','rfloordiv','pow','rpow','truediv','rtruediv'}
if arr.dtype.kind == 'b' and op_name in bool_ops:
    arr = arr.astype('Int8')
result = getattr(arr, '__' + op_name + '__')(other)

Type guard

def bool_op_is_defined(arr, op_name) -> bool:
    return not (arr.dtype.kind == 'b' and op_name in {'floordiv','rfloordiv','pow','rpow','truediv','rtruediv'})

Try / catch

try:
    result = arr // 2
except NotImplementedError as e:
    if 'not implemented for bool' in str(e):
        result = arr.astype('Int8') // 2
    else:
        raise

Prevention

When it happens

Trigger: Computing bool_arr // 2, bool_arr ** 2, bool_arr / 2 (and the reflected variants) on a pandas 'boolean' ExtensionArray.

Common situations: Treating a boolean column as 0/1 integers in arithmetic; feature engineering that divides or exponentiates flag columns; porting numpy bool math (which casts to int) to pandas nullable boolean.

Related errors


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

Appendix: source

Thrown at pandas/core/arrays/masked.py:1017

            #  e.g. test_array_scalar_like_equivalence
            other = bool(other)

        mask = self._propagate_mask(omask, other)

        if other is libmissing.NA:
            result = np.ones_like(self._data)
            if self.dtype.kind == "b":
                if op_name in {
                    "floordiv",
                    "rfloordiv",
                    "pow",
                    "rpow",
                    "truediv",
                    "rtruediv",
                }:
                    # GH#41165 Try to match non-masked Series behavior
                    #  This is still imperfect GH#46043
                    raise NotImplementedError(
                        f"operator '{op_name}' not implemented for bool dtypes"
                    )
                if op_name in {"mod", "rmod"}:
                    dtype = "int8"
                else:
                    dtype = "bool"
                result = result.astype(dtype)
            elif "truediv" in op_name and self.dtype.kind != "f":
                # The actual data here doesn't matter since the mask
                #  will be all-True, but since this is division, we want
                #  to end up with floating dtype.
                result = result.astype(np.float64)
            elif op_name in {"divmod", "rdivmod"}:
                # GH#62196
                res = self._maybe_mask_result(result, mask)
                return res, res.copy()
        else:
            # Make sure we do this before the "pow" mask checks

View on GitHub (pinned to 3b7651241d)