{"record":{"id":"31416330151aee5a","repo":"pola-rs/polars","slug":"data-type-dtype-r-not-supported-by-the-interchan","errorCode":null,"errorMessage":"data type {dtype!r} not supported by the interchange protocol","messagePattern":"data type (.+?) not supported by the interchange protocol","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/utils.py","lineNumber":65,"sourceCode":"    Float64: (DtypeKind.FLOAT, 64, \"g\", NE),\n    Boolean: (DtypeKind.BOOL, 1, \"b\", NE),\n    String: (DtypeKind.STRING, 8, \"U\", NE),\n    Date: (DtypeKind.DATETIME, 32, \"tdD\", NE),\n    Time: (DtypeKind.DATETIME, 64, \"ttu\", NE),\n    Datetime: (DtypeKind.DATETIME, 64, \"tsu:\", NE),\n    Duration: (DtypeKind.DATETIME, 64, \"tDu\", NE),\n    Categorical: (DtypeKind.CATEGORICAL, 32, \"I\", NE),\n    Enum: (DtypeKind.CATEGORICAL, 32, \"I\", NE),\n}\n\n\ndef polars_dtype_to_dtype(dtype: PolarsDataType) -> Dtype:\n    \"\"\"Convert Polars data type to interchange protocol data type.\"\"\"\n    try:\n        result = polars_dtype_to_dtype_map[dtype.base_type()]\n    except KeyError as exc:\n        msg = f\"data type {dtype!r} not supported by the interchange protocol\"\n        raise ValueError(msg) from exc\n\n    # Handle instantiated data types\n    if isinstance(dtype, Datetime):\n        return _datetime_to_dtype(dtype)\n    elif isinstance(dtype, Duration):\n        return _duration_to_dtype(dtype)\n\n    return result\n\n\ndef _datetime_to_dtype(dtype: Datetime) -> Dtype:\n    tu = dtype.time_unit[0]\n    tz = dtype.time_zone if dtype.time_zone is not None else \"\"\n    arrow_c_type = f\"ts{tu}:{tz}\"\n    return DtypeKind.DATETIME, 64, arrow_c_type, NE\n\n\ndef _duration_to_dtype(dtype: Duration) -> Dtype:","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/pola-rs/polars/blob/9b5d73fd00236295624374b075d16b1fe6ec6df9/py-polars/src/polars/interchange/utils.py#L47-L83","documentation":"When a Polars DataFrame is exported through the dataframe interchange protocol, each column's dtype is mapped via a fixed lookup table covering primitives (bool, ints, floats), String, Date, Datetime, Duration, Categorical and Enum. Any dtype outside that table — nested types (List, Struct, Array), Binary, Object, Null, Decimal, Time — raises ValueError('data type ... not supported by the interchange protocol').","triggerScenarios":"An interchange consumer (another library calling df.__dataframe__()) inspects a Polars DataFrame containing List/Struct/Array/Object/Binary columns; also selecting such columns before exporting via the protocol. The Datetime/Duration entries are special-cased afterward for time unit and time zone.","commonSituations":"Feeding nested Polars data to interchange-only consumers; ML/interop tools that only speak the interchange protocol; mixed frames where one Object column (from .to_objects or Python objects) breaks the whole export.","solutions":["Drop or stringify unsupported columns before interchange: df.select(pl.col('nested').cast(pl.String)) or .drop('nested').","Use the Arrow path for nested data: df.write_arrow / pl.from_arrow, which supports List and Struct natively.","If the consumer supports it, serialize nested columns to JSON strings and decode after transfer."],"exampleFix":"# before\nicdf = df.__dataframe__()  # List/Struct/Object column -> ValueError\n\n# after\ndf_flat = df.with_columns(pl.col(\"payload\").cast(pl.String))  # or .drop(\"payload\")\nicdf = df_flat.__dataframe__()","handlingStrategy":"validation","validationCode":"INTERCHANGE_SUPPORTED = {\n    pl.Boolean, pl.Int8, pl.Int16, pl.Int32, pl.Int64,\n    pl.UInt8, pl.UInt16, pl.UInt32, pl.UInt64,\n    pl.Float32, pl.Float64, pl.String, pl.Date,\n    pl.Datetime, pl.Duration, pl.Categorical, pl.Enum,\n}\n\nunsupported = [\n    name for name, dtype in df.schema.items()\n    if dtype.base_type() not in INTERCHANGE_SUPPORTED\n]\nexport_df = df.drop(unsupported) if unsupported else df\nicdf = export_df.__dataframe__()","typeGuard":"def interchange_safe(df: pl.DataFrame) -> bool:\n    nested_or_exotic = {pl.List, pl.Struct, pl.Array, pl.Object, pl.Binary, pl.Null}\n    return all(dt.base_type() not in nested_or_exotic for dt in df.schema.values())","tryCatchPattern":null,"preventionTips":["Flatten or stringify nested columns (List/Struct/Array) before interchange export.","Avoid Object columns entirely; cast them to String early in the pipeline.","Use the Arrow path (to_arrow/from_arrow) when nested types must cross library boundaries."],"tags":["polars","interchange-protocol","dtype","nested-types","valueerror"],"backgroundTag":"dtype-not-supported","analyzedSha":"9b5d73fd00236295624374b075d16b1fe6ec6df9","analyzedAt":"2026-08-19T12:15:06.350Z","contentChangedAt":"2026-08-19T12:15:06.350Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}