{"record":{"id":"b51975f285c4e105","repo":"pola-rs/polars","slug":"unsupported-operand-type-s-for-op-selector","errorCode":null,"errorMessage":"unsupported operand type(s) for op: ('Selector' + 'Selector')","messagePattern":"unsupported operand type\\(s\\) for op: \\('Selector' \\+ 'Selector'\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/selectors.py","lineNumber":463,"sourceCode":"    def _by_name(\n        cls, names: builtins.list[str], *, strict: bool, expand_patterns: bool\n    ) -> Selector:\n        return cls._from_pyselector(PySelector.by_name(names, strict, expand_patterns))\n\n    def __invert__(cls) -> Selector:\n        \"\"\"Invert the selector.\"\"\"\n        return all() - cls\n\n    def __add__(self, other: Any) -> Expr:\n        if is_selector(other):\n            return self.as_expr().__add__(other.as_expr())\n        else:\n            return self.as_expr().__add__(other)\n\n    def __radd__(self, other: Any) -> Expr:\n        if is_selector(other):\n            msg = \"unsupported operand type(s) for op: ('Selector' + 'Selector')\"\n            raise TypeError(msg)\n        else:\n            return self.as_expr().__radd__(other)\n\n    @overload\n    def __and__(self, other: Selector) -> Selector: ...\n\n    @overload\n    def __and__(self, other: Any) -> Expr: ...\n\n    def __and__(self, other: Any) -> Selector | Expr:\n        if is_column(other):  # @2.0: remove\n            colname = other.meta.output_name()\n            other = by_name(colname)\n        if is_selector(other):\n            return Selector._from_pyselector(\n                PySelector.intersect(self._pyselector, other._pyselector)\n            )\n        else:","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/selectors.py#L445-L481","documentation":"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.","triggerScenarios":"Writing cs.a() + cs.b() intending column union; reflected addition paths where the left selector's __add__ defers; subclassed selectors combined with +.","commonSituations":"Users arriving from other libraries where + concatenates selections; code generators emitting `sel1 + sel2` for column sets.","solutions":["For set union use the or-operator: cs.numeric() | cs.by_name('id')","If arithmetic addition of the selected columns is truly intended, go through expressions after selection instead of relying on reflected selector arithmetic","Review any code building selectors with operator(+ ) and switch to | or &"],"exampleFix":"# before\nsel = cs.first() + cs.last()   # TypeError on reflected path; ambiguous anyway\n\n# after\nsel = cs.first() | cs.last()    # union","handlingStrategy":"type-guard","validationCode":"from polars.selectors import is_selector\nif is_selector(a) and is_selector(b):\n    combined = a | b  # union, never '+'\nelse:\n    combined = a + b","typeGuard":"from polars.selectors import is_selector\n\ndef safe_union(a, b):\n    if is_selector(a) and is_selector(b):\n        return a | b\n    raise TypeError('expected two selectors')","tryCatchPattern":null,"preventionTips":["Mental model: selectors are column SETS - |, &, - are set ops; +/-/* are value arithmetic","Lint for '+' between cs.* expressions in review"],"tags":["polars","selectors","operator-misuse","type-error"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}