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__ (the ~ operator) when the underlying pyarrow type is a string or large_string. Bitwise NOT is meaningless on strings, so pandas raises TypeError proactively rather than letting pyarrow raise ArrowNotImplementedError. Integer types use bit_wise_not; other types fall through to pc.invert.
Solutions
- If you intended a boolean negation, build the boolean mask first: ~s.eq(value) or ~s.isna().
- Cast to boolean explicitly before inverting: ~s.astype('boolean[pyarrow]').
- Avoid the ~ operator on string arrays; use s != value style comparisons.
- Check dtype.kind == 'b' before applying ~.
Example fix
# before
s = pd.Series(['a', 'b'], dtype="string[pyarrow]")
~s # raises TypeError
# after
~s.eq('a') # boolean mask, safe to invert Defensive patterns
Strategy: type-guard
Validate before calling
import pyarrow as pa
def safe_invert(arr):
if pa.types.is_string(arr._pa_array.type) or pa.types.is_large_string(arr._pa_array.type):
raise TypeError('cannot invert string array; build a boolean mask first')
return ~arr Type guard
import pyarrow as pa
def supports_invert(arr) -> bool:
t = arr._pa_array.type
return not (pa.types.is_string(t) or pa.types.is_large_string(t)) Try / catch
try:
result = ~arr
except TypeError as e:
if 'string dtypes' in str(e):
result = ~arr.astype('boolean[pyarrow]')
else:
raise Prevention
- Apply ~ only to boolean masks; build masks via comparisons first.
- Check dtype.kind == 'b' before inverting.
- Watch for pyarrow string inference turning columns into string[pyarrow].
When it happens
Trigger: ~arr where arr is an ArrowExtensionArray of dtype string[pyarrow] or large_string[pyarrow]; applying the invert operator to a Series/Index backed by pyarrow strings; chained operations like ~s.isin(values) where s is already boolean-string.
Common situations: Inverting a boolean mask but the Series dtype drifted to string[pyarrow]; pyarrow string inference (PD_IO_* infer_string) turning object columns into strings; migrating from object dtype where ~ on object sometimes 'worked' by accident.
Related errors
- operation ' ' not supported for dtype ' ' with
- Can only string multiply by an integer.
- unary '-' not supported for dtype
- DateOffset is intra-day and cannot be applied to…
- empty separator
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/b9c029651b7a2a59.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/arrow/array.py:1065
# 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 onceView on GitHub (pinned to 3b7651241d)