pola-rs/polars · error · TypeError

expected one or more `str`, `DataType` or selector; found {i

Error message

expected one or more `str`, `DataType` or selector; found {item!r} instead.

What it means

_combine_as_selector (the engine behind cs.exclude and similar selector combinators) accepts only: strings (a ^...$ string is treated as regex), polars dtypes, Selectors, column expressions, or collections of those. Any other item type (int, numpy scalar, Series, arbitrary object) raises TypeError.

Source

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

            if isinstance(items, Collection) and not isinstance(items, str)
            else [items]
        ),
        *more_items,
    ):
        if is_selector(item):
            selectors.append(item)
        elif is_polars_dtype(item):
            dtypes.append(item)
        elif isinstance(item, str):
            if item.startswith("^") and item.endswith("$"):
                regexes.append(item)
            else:
                names.append(item)
        elif is_column(item):
            names.append(item.meta.output_name())  # type: ignore[union-attr]
        else:
            msg = f"expected one or more `str`, `DataType` or selector; found {item!r} instead."
            raise TypeError(msg)

    selected = []
    if names:
        selected.append(by_name(*names, require_all=False))
    if dtypes:
        selected.append(by_dtype(*dtypes))
    if regexes:
        selected.append(
            matches(
                "|".join(f"({rx})" for rx in regexes)
                if len(regexes) > 1
                else regexes[0]
            )
        )
    if selectors:
        selected.extend(selectors)

    return reduce(or_, selected)

View on GitHub (pinned to df599052da)

Solutions

  1. Convert indices to names first: cs.exclude(df.columns[0], 'b')
  2. Pass dtypes or selectors instead of raw objects: cs.exclude(cs.string())
  3. For Series pass its name: cs.exclude(df['col'].name)

Example fix

# before
df.select(cs.exclude(0, 'b'))

# after
df.select(cs.exclude(df.columns[0], 'b'))
Defensive patterns

Strategy: type-guard

Validate before calling

from polars.selectors import is_selector
from polars.datatypes import is_polars_dtype

def _ok(item):
    return isinstance(item, str) or is_selector(item) or is_polars_dtype(item) or item.meta.is_column() if hasattr(item, 'meta') else isinstance(item, str)

items = [df.columns[i] if isinstance(i, int) else i for i in items]  # normalize indices

Type guard

from polars.selectors import is_selector
from polars.datatypes import is_polars_dtype

def is_selector_input(item) -> bool:
    return (
        isinstance(item, str)
        or is_selector(item)
        or is_polars_dtype(item)
        or (hasattr(item, 'meta') and item.meta.is_column())
    )

Prevention

When it happens

Trigger: cs.exclude(0) (pandas-style index); cs.exclude(np.int64(3)); cs.exclude(df['col']) (a Series); tuples mixing valid and invalid items.

Common situations: Porting pandas drop-by-index habits; numpy ints arriving from computed index positions; passing a Series instead of its name.

Related errors


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