{"record":{"id":"a48b2d4cffd8e46f","repo":"pandas-dev/pandas","slug":"unary-not-supported-for-dtype-self-dtype","errorCode":null,"errorMessage":"unary '-' not supported for dtype '{self.dtype}'","messagePattern":"unary '-' not supported for dtype '(.+?)'","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":1048,"sourceCode":"        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\n    # https://issues.apache.org/jira/browse/ARROW-10739 is addressed\n    def __getstate__(self):\n        state = self.__dict__.copy()\n        state[\"_pa_array\"] = self._pa_array.combine_chunks()\n        # cached properties can be recomputed; don't bloat the pickle\n        state[\"_cache\"] = {}\n        return state\n","sourceCodeStart":1030,"sourceCodeEnd":1066,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L1030-L1066","documentation":"Raised by ArrowExtensionArray.__neg__ (- operator) when pc.negate_checked raises ArrowNotImplementedError — i.e. the dtype has no negation (strings, bool, temporal types without negate, unsigned integers can also overflow). pandas re-raises as TypeError with a clear message naming the dtype, instead of leaking pyarrow's exception. Other dtypes (signed int, float) negate normally.","triggerScenarios":"`-s` on a pyarrow-backed string/bool/timestamp/bool array: `-pd.Series(['a'], dtype='string[pyarrow]')`, `-pd.Series([True,False], dtype='bool[pyarrow]')`. Also unsigned int overflow if the value can't be negated.","commonSituations":"Generic arithmetic pipelines applying unary minus to all numeric-looking columns; mixing dtypes after convert_dtypes(dtype_backend='pyarrow') turning a former int column into bool. Migration from numpy-backed where bool negation raised differently.","solutions":["Skip non-numeric dtypes: if s.dtype.kind in 'iuf': -s.","Cast to a negate-able type first: -s.astype('int64[pyarrow]').","Use logical not (~) for boolean arrays instead of arithmetic negation.","Filter columns by dtype before applying vectorized negation."],"exampleFix":"# before\nout = -df.select_dtypes('number')  # fails if bool[pyarrow] included\n# after\nnumeric = df.select_dtypes(['int64[pyarrow]','float64[pyarrow]','int64','float64'])\nout = -numeric","handlingStrategy":"type-guard","validationCode":"import pyarrow as pa\nfrom pandas.core.arrays.arrow import ArrowExtensionArray\n\ndef negate_if_supported(arr):\n    if isinstance(arr, ArrowExtensionArray):\n        t = arr._pa_array.type\n        if not (pa.types.is_integer(t) or pa.types.is_floating(t) or pa.types.is_decimal(t)):\n            raise TypeError(f'cannot negate dtype {arr.dtype}')\n    return -arr\n\nout = negate_if_supported(col)","typeGuard":"import pyarrow as pa\nfrom pandas.core.arrays.arrow import ArrowExtensionArray\n\ndef is_negatable_arrow_array(arr) -> bool:\n    if not isinstance(arr, ArrowExtensionArray):\n        return True\n    t = arr._pa_array.type\n    return pa.types.is_integer(t) or pa.types.is_floating(t) or pa.types.is_decimal(t)","tryCatchPattern":"try:\n    out = -col\nexcept TypeError as e:\n    if 'unary' in str(e):\n        # skip non-numeric, or cast\n        out = col  # or col.astype('float64[pyarrow]') then negate\n    else:\n        raise","preventionTips":["Filter to numeric dtypes before applying vectorized negation.","Use ~ for boolean negation, not -.","Type-check at column iteration boundaries."],"tags":["pyarrow","unary-op","dtype-validation","type-error"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}