{"record":{"id":"1a0d987520002306","repo":"pola-rs/polars","slug":"non-dictionary-categoricals-are-not-yet-supported","errorCode":null,"errorMessage":"non-dictionary categoricals are not yet supported","messagePattern":"non-dictionary categoricals are not yet supported","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/from_dataframe.py","lineNumber":150,"sourceCode":"    data = pl.Series._from_buffers(String, data=data_buffers, validity=None)\n\n    # Add the validity buffer if present\n    validity_buffer = _construct_validity_buffer(\n        buffers[\"validity\"], column, String, data, offset, allow_copy=allow_copy\n    )\n    if validity_buffer is not None:\n        data = pl.Series._from_buffers(\n            String, data=data_buffers, validity=validity_buffer\n        )\n\n    return data\n\n\ndef _categorical_column_to_series(column: Column, *, allow_copy: bool) -> Series:\n    categorical = column.describe_categorical\n    if not categorical[\"is_dictionary\"]:\n        msg = \"non-dictionary categoricals are not yet supported\"\n        raise NotImplementedError(msg)\n\n    categories_col = categorical[\"categories\"]\n    if categories_col.size() == 0:\n        dtype = Enum([])\n    elif categories_col.dtype[0] != DtypeKind.STRING:\n        msg = \"non-string categories are not supported\"\n        raise NotImplementedError(msg)\n    else:\n        categories = _string_column_to_series(categories_col, allow_copy=allow_copy)\n        dtype = Enum(categories)\n\n    buffers = column.get_buffers()\n    offset = column.offset\n\n    data_buffer = _construct_data_buffer(\n        *buffers[\"data\"], column.size(), offset, allow_copy=allow_copy\n    )\n    validity_buffer = _construct_validity_buffer(","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/interchange/from_dataframe.py#L132-L168","documentation":"Polars can only import categorical columns that are dictionary-encoded, i.e. describe_categorical()['is_dictionary'] is True. A producer reporting is_dictionary=False advertises a categorical without a categories dictionary, which has no Polars equivalent on the import path, so Polars raises NotImplementedError instead of guessing.","triggerScenarios":"Consuming a categorical column from a producer whose describe_categorical() returns is_dictionary=False.","commonSituations":"Custom producers exposing non-dictionary categorical systems; early adopters of extended interchange features; porting pandas.Categorical-like semantics where the mapping is implicit rather than dictionary-encoded.","solutions":["Change the producer to dictionary-encode the column and report is_dictionary=True","Expose the column as plain string or integer data instead of categorical","Convert the column upstream (e.g. cast to string in the source system) before interchange conversion"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def categorical_columns_are_dictionary_encoded(df) -> bool:\n    from polars.interchange.protocol import DtypeKind\n    proto = df.__dataframe__(allow_copy=False)\n    for col in proto.get_columns():\n        if col.dtype[0] == DtypeKind.CATEGORICAL:\n            if not col.describe_categorical()['is_dictionary']:\n                return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    out = pl.from_dataframe(df)\nexcept NotImplementedError as e:\n    if 'non-dictionary categoricals' in str(e):\n        # ask producer for plain strings or fix its encoding\n        raise\n    raise","preventionTips":["Producers: always dictionary-encode categorical columns and set is_dictionary=True","Audit custom producers for categorical metadata correctness before shipping","Prefer exporting categoricals as plain strings when in doubt - polars can re-encode them"],"tags":["polars","interchange-protocol","categorical","not-implemented","producer-bug"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}