pola-rs/polars · error · TypeError

cannot convert Python type

Error message

cannot convert Python type {qualified_type_name(el)!r} to {dtype!r}

What it means

maybe_cast tries to coerce an element to the target Polars dtype's Python type; when the conversion (py_type(el)) fails, it raises TypeError naming the source Python type and target dtype. It enforces strict element-type compatibility when building Series from sequences.

Solutions

  1. Clean/pre-cast the data: [int(v) for v in values] or coerce with pandas/numpy beforehand.
  2. Build the Series without a strict dtype and cast after with .cast(dtype, strict=False), filtering nulls.
  3. Filter or fix offending rows before constructing the Series.

Example fix

// before
pl.Series(["1", "2", "oops"], dtype=pl.Int64)  # TypeError
// after
pl.Series(["1", "2", "oops"]).cast(pl.Int64, strict=False)  # null where cast fails
Defensive patterns

Strategy: try-catch

Validate before calling

def castable(values, dtype) -> bool:
    py_t = {pl.Int64: int, pl.Float64: float, pl.Utf8: str, pl.Boolean: bool}.get(dtype.base_type())
    return py_t is None or all(isinstance(v, py_t) or v is None for v in values)

Type guard

def all_ints(values: list[object]) -> TypeGuard[list[int]]:
    return all(isinstance(v, int) or v is None for v in values)

Try / catch

try:
    s = pl.Series(values, dtype=dtype)
except TypeError as e:
    if "cannot convert Python type" in str(e):
        s = pl.Series(values).cast(dtype, strict=False)
    else:
        raise

Prevention

When it happens

Trigger: pl.Series('x', ['a', 1], dtype=pl.Int64) where 'a' cannot be int()-ed; passing None mixed with strict=False only allowing null for the right dtype; passing dicts where scalars are expected; passing arbitrary objects to numeric dtypes.

Common situations: Dirty CSV/JSON data with stray strings in numeric columns; mixed-type lists from parsed logs; numpy scalars of the wrong width; booleans mixed with ints under an Int dtype.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/fee533d281f1f287. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/datatypes/convert.py:366

    )

    time_unit: TimeUnit
    if isinstance(el, datetime):
        time_unit = getattr(dtype, "time_unit", "us")
        return datetime_to_int(el, time_unit)
    elif isinstance(el, timedelta):
        time_unit = getattr(dtype, "time_unit", "us")
        return timedelta_to_int(el, time_unit)

    py_type = dtype_to_py_type(dtype)
    if not isinstance(el, py_type):
        try:
            el = py_type(el)  # type: ignore[call-arg]
        except Exception:
            from polars._utils.various import qualified_type_name

            msg = f"cannot convert Python type {qualified_type_name(el)!r} to {dtype!r}"
            raise TypeError(msg) from None
    return el

View on GitHub (pinned to fe841f959e)