{"record":{"id":"b9c029651b7a2a59","repo":"pandas-dev/pandas","slug":"invert-is-not-supported-for-string-dtypes","errorCode":null,"errorMessage":"__invert__ is not supported for string dtypes","messagePattern":"__invert__ is not supported for string dtypes","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":1040,"sourceCode":"            # TODO: By using `zero_copy_only` it may be possible to implement this\n            raise ValueError(\n                \"Unable to avoid copy while creating an array as requested.\"\n            )\n        elif copy is None:\n            # `to_numpy(copy=False)` has the meaning of NumPy `copy=None`.\n            copy = False\n\n        return self.to_numpy(dtype=dtype, copy=copy)\n\n    def __invert__(self) -> Self:\n        # This is a bit wise op for integer types\n        if pa.types.is_integer(self._pa_array.type):\n            return self._from_pyarrow_array(pc.bit_wise_not(self._pa_array))\n        elif pa.types.is_string(self._pa_array.type) or pa.types.is_large_string(\n            self._pa_array.type\n        ):\n            # Raise TypeError instead of pa.ArrowNotImplementedError\n            raise TypeError(\"__invert__ is not supported for string dtypes\")\n        else:\n            return self._from_pyarrow_array(pc.invert(self._pa_array))\n\n    def __neg__(self) -> Self:\n        try:\n            return self._from_pyarrow_array(pc.negate_checked(self._pa_array))\n        except pa.ArrowNotImplementedError as err:\n            raise TypeError(\n                f\"unary '-' not supported for dtype '{self.dtype}'\"\n            ) from err\n\n    def __pos__(self) -> Self:\n        return self._from_pyarrow_array(self._pa_array)\n\n    def __abs__(self) -> Self:\n        return self._from_pyarrow_array(pc.abs_checked(self._pa_array))\n\n    # GH 42600: __getstate__/__setstate__ not necessary once","sourceCodeStart":1022,"sourceCodeEnd":1058,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L1022-L1058","documentation":"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.","triggerScenarios":"`~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.","commonSituations":"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.","solutions":["Verify dtype is boolean before inverting: if s.dtype.kind == 'b': ~s.","Cast to bool explicitly if the strings are truthy/falsy representations: ~s.astype('bool[pyarrow]').","Select the correct (boolean) column for the mask.","Wrap with try/except TypeError if iterating heterogeneous columns."],"exampleFix":"# before\nmask = ~df['category']  # TypeError if category is string[pyarrow]\n# after\nmask = ~df['is_active']  # boolean column\n# or explicit cast when semantics are defined\nmask = ~df['category'].astype('bool[pyarrow]')","handlingStrategy":"type-guard","validationCode":"def invert_if_bool(arr):\n    import pyarrow as pa\n    from pandas.core.arrays.arrow import ArrowExtensionArray\n    if isinstance(arr, ArrowExtensionArray):\n        t = arr._pa_array.type\n        if pa.types.is_string(t) or pa.types.is_large_string(t):\n            raise TypeError('cannot invert string array; cast to bool first')\n    return ~arr\n\nmask = invert_if_bool(col)","typeGuard":"import pyarrow as pa\nfrom pandas.core.arrays.arrow import ArrowExtensionArray\n\ndef is_invertible_arrow_array(arr) -> bool:\n    if not isinstance(arr, ArrowExtensionArray):\n        return True\n    t = arr._pa_array.type\n    return not (pa.types.is_string(t) or pa.types.is_large_string(t))","tryCatchPattern":"try:\n    out = ~col\nexcept TypeError as e:\n    if '__invert__ is not supported for string dtypes' in str(e):\n        out = ~col.astype('bool[pyarrow]')\n    else:\n        raise","preventionTips":["Verify dtype.kind == 'b' before applying ~ to a column.","Build masks only from boolean expressions, not raw columns.","Type-check heterogeneous columns in generic invert pipelines."],"tags":["pyarrow","unary-op","string-dtype","type-error"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}