pandas-dev/pandas · error · TypeError

__invert__ is not supported for string dtypes

Error message

__invert__ is not supported for string dtypes

What it means

Raised by ArrowExtensionArray.__invert__ (~ operator) when the underlying pyarrow type is string or large_string. Integer types use bit_wise_not and other types use pc.invert, but strings have no meaningful bitwise inversion, so pandas raises TypeError proactively rather than letting pyarrow raise ArrowNotImplementedError. This keeps the error surface consistent with the rest of pandas.

Source

Thrown at pandas/core/arrays/arrow/array.py:1040

            # TODO: By using `zero_copy_only` it may be possible to implement this
            raise ValueError(
                "Unable to avoid copy while creating an array as requested."
            )
        elif copy is None:
            # `to_numpy(copy=False)` has the meaning of NumPy `copy=None`.
            copy = False

        return self.to_numpy(dtype=dtype, copy=copy)

    def __invert__(self) -> Self:
        # This is a bit wise op for integer types
        if pa.types.is_integer(self._pa_array.type):
            return self._from_pyarrow_array(pc.bit_wise_not(self._pa_array))
        elif pa.types.is_string(self._pa_array.type) or pa.types.is_large_string(
            self._pa_array.type
        ):
            # Raise TypeError instead of pa.ArrowNotImplementedError
            raise TypeError("__invert__ is not supported for string dtypes")
        else:
            return self._from_pyarrow_array(pc.invert(self._pa_array))

    def __neg__(self) -> Self:
        try:
            return self._from_pyarrow_array(pc.negate_checked(self._pa_array))
        except pa.ArrowNotImplementedError as err:
            raise TypeError(
                f"unary '-' not supported for dtype '{self.dtype}'"
            ) from err

    def __pos__(self) -> Self:
        return self._from_pyarrow_array(self._pa_array)

    def __abs__(self) -> Self:
        return self._from_pyarrow_array(pc.abs_checked(self._pa_array))

    # GH 42600: __getstate__/__setstate__ not necessary once

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Verify dtype is boolean before inverting: if s.dtype.kind == 'b': ~s.
  2. Cast to bool explicitly if the strings are truthy/falsy representations: ~s.astype('bool[pyarrow]').
  3. Select the correct (boolean) column for the mask.
  4. Wrap with try/except TypeError if iterating heterogeneous columns.

Example fix

# before
mask = ~df['category']  # TypeError if category is string[pyarrow]
# after
mask = ~df['is_active']  # boolean column
# or explicit cast when semantics are defined
mask = ~df['category'].astype('bool[pyarrow]')
Defensive patterns

Strategy: type-guard

Validate before calling

def invert_if_bool(arr):
    import pyarrow as pa
    from pandas.core.arrays.arrow import ArrowExtensionArray
    if isinstance(arr, ArrowExtensionArray):
        t = arr._pa_array.type
        if pa.types.is_string(t) or pa.types.is_large_string(t):
            raise TypeError('cannot invert string array; cast to bool first')
    return ~arr

mask = invert_if_bool(col)

Type guard

import pyarrow as pa
from pandas.core.arrays.arrow import ArrowExtensionArray

def is_invertible_arrow_array(arr) -> bool:
    if not isinstance(arr, ArrowExtensionArray):
        return True
    t = arr._pa_array.type
    return not (pa.types.is_string(t) or pa.types.is_large_string(t))

Try / catch

try:
    out = ~col
except TypeError as e:
    if '__invert__ is not supported for string dtypes' in str(e):
        out = ~col.astype('bool[pyarrow]')
    else:
        raise

Prevention

When it happens

Trigger: `~s` where s is a pyarrow-backed string Series/array: `pd.Series(['a','b'], dtype='string[pyarrow]')` then `~s`. Also calling .__invert__() directly or via operator.invert.

Common situations: Applying boolean-inversion idioms (~mask) to a string column by accident (wrong column reference), or generic pipelines that apply ~ to all columns. Common in filter builders that assume boolean dtype.

Related errors


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