pola-rs/polars · error · NotImplementedError

functionality for `nan_as_null` has not been implemented and

Error message

functionality for `nan_as_null` has not been implemented and the parameter will be removed in a future version

Use the default `nan_as_null=False`.

What it means

The dataframe interchange protocol's nan_as_null=True semantics (mapping NaN to null during interchange) were never implemented in polars, and the parameter is slated for removal from the protocol. DataFrame.__dataframe__ therefore raises NotImplementedError whenever anything but the default False is passed, instead of returning incorrect null semantics.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:1086

        Examples
        --------
        Convert a Polars DataFrame to a generic dataframe object and access some
        properties.

        >>> df = pl.DataFrame({"a": [1, 2], "b": [3.0, 4.0], "c": ["x", "y"]})
        >>> dfi = df.__dataframe__()  # doctest: +SKIP
        >>> dfi.num_rows()  # doctest: +SKIP
        2
        >>> dfi.get_column(1).dtype  # doctest: +SKIP
        (<DtypeKind.FLOAT: 2>, 64, 'g', '=')
        """
        if nan_as_null:
            msg = (
                "functionality for `nan_as_null` has not been implemented and the"
                " parameter will be removed in a future version"
                "\n\nUse the default `nan_as_null=False`."
            )
            raise NotImplementedError(msg)

        from polars.interchange.dataframe import PolarsDataFrame

        return PolarsDataFrame(self, allow_copy=allow_copy)

    def _comp(self, other: Any, op: ComparisonOperator) -> DataFrame:
        """Compare a DataFrame with another object."""
        if isinstance(other, DataFrame):
            return self._compare_to_other_df(other, op)
        else:
            return self._compare_to_non_df(other, op)

    def _compare_to_other_df(
        self,
        other: DataFrame,
        op: ComparisonOperator,
    ) -> DataFrame:
        """Compare a DataFrame with another DataFrame."""

View on GitHub (pinned to df599052da)

Solutions

  1. Call with the default: df.__dataframe__() or df.__dataframe__(allow_copy=...)
  2. If a consumer insists on nan-as-null, convert in polars first: df.with_columns(pl.col(pl.Float64).fill_nan(None)) then interchange without the flag
  3. Upgrade the consumer library to a version that no longer passes nan_as_null

Example fix

# before
interchange_object = df.__dataframe__(nan_as_null=True)

# after
df = df.with_columns(pl.col(pl.Float64).fill_nan(None))
interchange_object = df.__dataframe__()
Defensive patterns

Strategy: validation

Validate before calling

if nan_as_null:
    df = df.with_columns(pl.col(pl.Float64).fill_nan(None))
    nan_as_null = False  # use protocol default afterwards
dfi = df.__dataframe__(allow_copy=allow_copy)

Prevention

When it happens

Trigger: df.__dataframe__(nan_as_null=True) called directly; an interchange consumer library (older versions of dataframe protocol clients, some plotting/validation tools) passing nan_as_null=True explicitly; wrapper code forwarding user kwargs into __dataframe__.

Common situations: Third-party libs written against early interchange-protocol drafts; upgrade scripts that set the flag 'for safety' and thereby break every float frame containing NaN; testing harnesses enumerating all protocol parameters.

Related errors


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