{"record":{"id":"66f6e3ab345c124c","repo":"pola-rs/polars","slug":"names-is-not-a-sequence","errorCode":null,"errorMessage":"`names` is not a sequence","messagePattern":"`names` is not a sequence","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/dataframe.py","lineNumber":158,"sourceCode":"            indices = list(indices)\n\n        return PolarsDataFrame(\n            self._df[:, indices],\n            allow_copy=self._allow_copy,\n        )\n\n    def select_columns_by_name(self, names: Sequence[str]) -> PolarsDataFrame:\n        \"\"\"\n        Create a new dataframe by selecting a subset of columns by name.\n\n        Parameters\n        ----------\n        names\n            Column names.\n        \"\"\"\n        if not isinstance(names, Sequence):\n            msg = \"`names` is not a sequence\"\n            raise TypeError(msg)\n\n        return PolarsDataFrame(\n            self._df.select(names),\n            allow_copy=self._allow_copy,\n        )\n\n    def get_chunks(self, n_chunks: int | None = None) -> Iterator[PolarsDataFrame]:\n        \"\"\"\n        Return an iterator yielding the chunks of the dataframe.\n\n        Parameters\n        ----------\n        n_chunks\n            The number of chunks to return. Must be a multiple of the number of chunks\n            in the dataframe. If set to `None` (default), returns all chunks.\n\n        Notes\n        -----","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/interchange/dataframe.py#L140-L176","documentation":"Raised by PolarsDataFrame.select_columns_by_name when the names argument is not a collections.abc.Sequence — a bare string, generator, set, or iterator. Note a single string is technically a Sequence of characters but usually indicates a caller bug; non-sequence iterables like sets/generators are the hard failures here.","triggerScenarios":"select_columns_by_name('a') with a single name; passing a generator of names; passing a set of column names; passing an iterator from map/filter.","commonSituations":"Consumers computing name subsets via set intersection/difference; single-column convenience paths; piping map(...) results directly into interchange calls.","solutions":["Wrap in a list: select_columns_by_name(list(names)); for a single name use ['a']","Materialize iterators/sets before calling","Validate with isinstance(names, Sequence) at your API boundary"],"exampleFix":"// before\ndf.__dataframe__().select_columns_by_name({'a', 'b'})\n// after\ndf.__dataframe__().select_columns_by_name(['a', 'b'])","handlingStrategy":"type-guard","validationCode":"from collections.abc import Sequence\n\nif not isinstance(names, Sequence) or isinstance(names, str):\n    names = [names] if isinstance(names, str) else list(names)","typeGuard":"from collections.abc import Sequence\n\ndef is_name_sequence(obj) -> bool:\n    return isinstance(obj, Sequence) and not isinstance(obj, str)","tryCatchPattern":"try:\n    dfi = dfi.select_columns_by_name(names)\nexcept TypeError:\n    dfi = dfi.select_columns_by_name(list(names))","preventionTips":["Wrap single names in a list eagerly","Convert set/generator results to sorted lists for deterministic column order"],"tags":["polars","interchange-protocol","type-validation","sequence"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}