pandas-dev/pandas · error · TypeError
bad operand type for unary +
Error message
bad operand type for unary +: '{self.dtype}' What it means
ArrowStringArray.__pos__ raises TypeError because unary + is meaningless for string data. numpy allows + on numeric arrays; pandas overrides __pos__ to refuse rather than silently return the original or coerce.
Solutions
- Remove unary + from string column handling.
- Guard numeric-only transforms with select_dtypes('number').
- If a no-op copy is required, use s.copy() explicitly.
Example fix
// before +s # TypeError on string[pyarrow] // after s.copy() # if a copy was intended
Defensive patterns
Strategy: type-guard
Validate before calling
def safe_unary_pos(s):
if pd.api.types.is_string_dtype(s):
raise TypeError('unary + not supported for string dtype')
return +s Type guard
def unary_pos_safe(series) -> bool:
return pd.api.types.is_numeric_dtype(series) Try / catch
try:
+s
except TypeError as e:
if 'unary +' in str(e):
s = s.copy() # if a no-op copy was intended
else:
raise Prevention
- Avoid unary + on string columns.
- Use select_dtypes('number') before numeric transforms.
- Use s.copy() for explicit no-op copies.
When it happens
Trigger: +s where s is a string[pyarrow] Series; np.positive(s) on a string column; applying operator.pos to the array.
Common situations: Generic numerical transforms that apply unary + to every column; using +x as a no-op copy across mixed-dtype frames.
Related errors
- ArrowStringArray requires a PyArrow (chunked) array of…
- Cannot perform reduction
- Invalid value for dtype 'str'. Value should be a string or…
- Invalid value ' ' for dtype 'str'. Value should be a string…
- Invalid value ' ' for dtype 'str'. Value should be a string…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/066a8d1b76c903b3.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/string_arrow.py:676
def _cmp_method(self, other, op):
if (
isinstance(other, (BaseStringArray, ArrowExtensionArray))
and self.dtype.na_value is not libmissing.NA
and other.dtype.na_value is libmissing.NA
):
# NA has priority of NaN semantics
return NotImplemented
result = super()._cmp_method(other, op)
if self.dtype.na_value is np.nan:
if op == operator.ne:
return result.to_numpy(np.bool_, na_value=True)
else:
return result.to_numpy(np.bool_, na_value=False)
return result
def __pos__(self) -> Self:
raise TypeError(f"bad operand type for unary +: '{self.dtype}'")
View on GitHub (pinned to 3b7651241d)