pola-rs/polars · error · TypeError

unsupported operand type(s) for op: ('Selector' + 'Selector'

Error message

unsupported operand type(s) for op: ('Selector' + 'Selector')

What it means

Between selectors, `+` is arithmetic addition of the selected columns' values, not set union. Selector.__radd__ (reached when Python falls back to reflected addition, e.g. a Selector subclass on the left deferring) explicitly raises TypeError when the other operand is also a Selector, rather than silently guessing between union and addition.

Source

Thrown at py-polars/src/polars/selectors.py:463

    def _by_name(
        cls, names: builtins.list[str], *, strict: bool, expand_patterns: bool
    ) -> Selector:
        return cls._from_pyselector(PySelector.by_name(names, strict, expand_patterns))

    def __invert__(cls) -> Selector:
        """Invert the selector."""
        return all() - cls

    def __add__(self, other: Any) -> Expr:
        if is_selector(other):
            return self.as_expr().__add__(other.as_expr())
        else:
            return self.as_expr().__add__(other)

    def __radd__(self, other: Any) -> Expr:
        if is_selector(other):
            msg = "unsupported operand type(s) for op: ('Selector' + 'Selector')"
            raise TypeError(msg)
        else:
            return self.as_expr().__radd__(other)

    @overload
    def __and__(self, other: Selector) -> Selector: ...

    @overload
    def __and__(self, other: Any) -> Expr: ...

    def __and__(self, other: Any) -> Selector | Expr:
        if is_column(other):  # @2.0: remove
            colname = other.meta.output_name()
            other = by_name(colname)
        if is_selector(other):
            return Selector._from_pyselector(
                PySelector.intersect(self._pyselector, other._pyselector)
            )
        else:

View on GitHub (pinned to df599052da)

Solutions

  1. For set union use the or-operator: cs.numeric() | cs.by_name('id')
  2. If arithmetic addition of the selected columns is truly intended, go through expressions after selection instead of relying on reflected selector arithmetic
  3. Review any code building selectors with operator(+ ) and switch to | or &

Example fix

# before
sel = cs.first() + cs.last()   # TypeError on reflected path; ambiguous anyway

# after
sel = cs.first() | cs.last()    # union
Defensive patterns

Strategy: type-guard

Validate before calling

from polars.selectors import is_selector
if is_selector(a) and is_selector(b):
    combined = a | b  # union, never '+'
else:
    combined = a + b

Type guard

from polars.selectors import is_selector

def safe_union(a, b):
    if is_selector(a) and is_selector(b):
        return a | b
    raise TypeError('expected two selectors')

Prevention

When it happens

Trigger: Writing cs.a() + cs.b() intending column union; reflected addition paths where the left selector's __add__ defers; subclassed selectors combined with +.

Common situations: Users arriving from other libraries where + concatenates selections; code generators emitting `sel1 + sel2` for column sets.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/b51975f285c4e105. Report an issue: GitHub.