pola-rs/polars · error

'float' object cannot be interpreted as a {python_dtype.__na

Error message

'float' object cannot be interpreted as a {python_dtype.__name__!r}

What it means

Polars temporal types (Date, Datetime, Duration, Time) are stored as integers, and constructing them from Python/NumPy values explicitly rejects floats: a float epoch could be silently truncated, corrupting timestamps. The source comment states the caller must cast to int first; violations raise this TypeError naming the target type.

Source

Thrown at py-polars/src/polars/_utils/construction/series.py:238

    if python_dtype is None:
        if value is None:
            constructor = polars_type_to_constructor(Null)
            return constructor(name, values, strict)

        # generic default dtype
        python_dtype = type(value)

    # temporal branch
    if issubclass(python_dtype, tuple(py_temporal_types)):
        if dtype is None:
            dtype = parse_into_dtype(python_dtype)  # construct from integer
        elif dtype in py_temporal_types:
            dtype = parse_into_dtype(dtype)

        values_dtype = None if value is None else try_parse_into_dtype(type(value))
        if values_dtype is not None and values_dtype.is_float():
            msg = f"'float' object cannot be interpreted as a {python_dtype.__name__!r}"
            raise TypeError(
                # we do not accept float values as temporal; if this is
                # required, the caller should explicitly cast to int first.
                msg
            )

        # We use the AnyValue builder to create the datetime array
        # We store the values internally as UTC and set the timezone
        py_series = PySeries.new_from_any_values(name, values, strict)

        time_unit = getattr(dtype, "time_unit", None)
        time_zone = getattr(dtype, "time_zone", None)

        if dtype.is_temporal() and values_dtype == String and dtype != Duration:
            s = wrap_s(py_series).str.strptime(dtype, strict=strict)  # type: ignore[arg-type]
        elif time_unit is not None and values_dtype != Date:
            s = wrap_s(py_series).dt.cast_time_unit(time_unit)
        else:
            s = wrap_s(py_series)

View on GitHub (pinned to df599052da)

Solutions

  1. Convert to integers first: [int(v) for v in values] or values.astype("int64").
  2. Use the dedicated epoch helper: pl.from_epoch(pl.Series(values).cast(pl.Int64), time_unit="s").
  3. If fractional seconds matter, scale then truncate: (values * 1_000_000).astype("int64") for microsecond Datetime.
  4. Or pass real datetime objects and let polars convert.

Example fix

// before
s = pl.Series("ts", [1700000000.0, 1700000060.0], dtype=pl.Datetime("us"))

// after
s = pl.from_epoch(pl.Series("ts", [1700000000, 1700000060]), time_unit="s")
Defensive patterns

Strategy: type-guard

Validate before calling

import numbers

if any(isinstance(v, float) for v in values):
    values = [int(v) for v in values]  # caller must decide truncation policy
s = pl.Series(name, values, dtype=pl.Datetime("us"))

Type guard

def has_no_floats(values) -> bool:
    return not any(isinstance(v, numbers.Real) and not isinstance(v, numbers.Integral) for v in values)

Try / catch

try:
    s = pl.Series(name, values, dtype=target_temporal_dtype)
except TypeError as e:
    if "cannot be interpreted as" in str(e):
        s = pl.Series(name, [int(v) for v in values], dtype=target_temporal_dtype)
    else:
        raise

Prevention

When it happens

Trigger: pl.Series([1.5e9, 1.6e9], dtype=pl.Datetime("us")); np.array([...], dtype="float64") passed with dtype=pl.Date; epoch values from JSON APIs arriving as floats.

Common situations: Unix timestamps returned as floats by APIs/databases; NumPy epoch arrays that default to float64; unit tests using round numbers like 1700000000.0.

Related errors


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