pola-rs/polars · error · TypeError

object does not support PyCapsule interface; found {obj!r}

Error message

object does not support PyCapsule interface; found {obj!r} 

What it means

pycapsule_to_frame (polars/_utils/pycapsule.py:48) ingests objects through the Arrow PyCapsule interface: it needs __arrow_c_array__ or __arrow_c_stream__. If the object exposes neither, it cannot be read as Arrow data and this TypeError is raised naming the object. Public entry points (pl.DataFrame(data) at frame.py:479, pl.from_arrow, pl.from_dataframe) pre-check with is_pycapsule(), so hitting this raise usually means the object's attributes were non-callable, removed between check and use, or an internal call bypassed the check.

Source

Thrown at py-polars/src/polars/_utils/pycapsule.py:48

    rechunk: bool = False,
) -> DataFrame:
    """Convert PyCapsule object to DataFrame."""
    if hasattr(obj, "__arrow_c_array__"):
        # This uses the fact that PySeries.from_arrow_c_array will create a
        # struct-typed Series. Then we unpack that to a DataFrame.
        tmp_col_name = ""
        s = wrap_s(PySeries.from_arrow_c_array(obj))
        df = s.to_frame(tmp_col_name).unnest(tmp_col_name)

    elif hasattr(obj, "__arrow_c_stream__"):
        # This uses the fact that PySeries.from_arrow_c_stream will create a
        # struct-typed Series. Then we unpack that to a DataFrame.
        tmp_col_name = ""
        s = wrap_s(PySeries.from_arrow_c_stream(obj))
        df = s.to_frame(tmp_col_name).unnest(tmp_col_name)
    else:
        msg = f"object does not support PyCapsule interface; found {obj!r} "
        raise TypeError(msg)

    if rechunk:
        df = df.rechunk()
    if schema or schema_overrides:
        df = wrap_df(
            dataframe_to_pydf(df, schema=schema, schema_overrides=schema_overrides)
        )
    return df

View on GitHub (pinned to df599052da)

Solutions

  1. Convert with the right constructor: pl.from_pandas(pdf), pl.from_numpy(arr), pl.from_dict(d)
  2. Pass an Arrow-native object: pyarrow.Table or one implementing __arrow_c_stream__/__arrow_c_array__
  3. Implement the Arrow PyCapsule Protocol on your class (expose __arrow_c_stream__ returning a PyCapsule)

Example fix

# before
pl.from_dataframe(pandas_df)  # no Arrow/interchange support found

# after
pl.from_pandas(pandas_df)  # or pl.from_arrow(pyarrow_table)
Defensive patterns

Strategy: type-guard

Validate before calling

def is_arrow_capsule(obj) -> bool:
    return any(
        callable(getattr(obj, attr, None))
        for attr in ("__arrow_c_stream__", "__arrow_c_array__")
    )

if not is_arrow_capsule(data) and not hasattr(data, "__dataframe__"):
    data = to_arrow_table(data)  # route pandas/numpy/dict through the right converter
pl.from_dataframe(data)

Type guard

def is_arrow_capsule(obj) -> bool:
    return any(
        callable(getattr(obj, attr, None))
        for attr in ("__arrow_c_stream__", "__arrow_c_array__")
    )

Prevention

When it happens

Trigger: pl.DataFrame(numpy_array) or pl.DataFrame(dict) will not hit this (other branches), but pl.from_dataframe(obj) where obj is a plain Python object (no __arrow_c_* or __dataframe__), or an object with non-callable __arrow_c_array__ attributes does; likewise passing a pandas DataFrame when no interchange path is available.

Common situations: Assuming from_dataframe accepts any table-like object; DuckDB/Arrow-producing libraries with partially implemented protocols; stub objects in tests missing the capsule methods.

Related errors


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