pola-rs/polars · error · ValueError

cannot construct PySeries for type

Error message

cannot construct PySeries for type {dtype!r}

What it means

polars_type_to_constructor looks up a PySeries constructor for a Polars dtype via _POLARS_TYPE_TO_CONSTRUCTOR[dtype.base_type()]; if the base type has no registered constructor a ValueError is thrown. It means polars' Rust backend cannot build a Series from Python sequences for this dtype.

Solutions

  1. Use a concrete supported dtype (pl.Int64, pl.Utf8, pl.List, pl.Array, pl.Struct, etc.) as the target dtype.
  2. For custom types, register them via polars.datatypes.extension.register_extension_type before use.
  3. Let polars infer the dtype instead of forcing an unsupported one, then cast afterwards with .cast().

Example fix

// before
pl.Series("x", [1, 2], dtype=pl.Unknown)
// after
pl.Series("x", [1, 2])  # let polars infer, or dtype=pl.Int64
Defensive patterns

Strategy: try-catch

Validate before calling

SUPPORTED_BASES = {pl.Int64, pl.Float64, pl.Utf8, pl.Boolean, pl.Date, pl.Datetime, pl.List, pl.Array, pl.Struct, pl.Binary}
assert getattr(dtype, 'base_type', lambda: dtype)() in SUPPORTED_BASES, f"unsupported dtype {dtype!r}"

Try / catch

try:
    s = pl.Series(name, values, dtype=dtype)
except ValueError as e:
    if "cannot construct PySeries" in str(e):
        s = pl.Series(name, values)  # infer, then cast
    else:
        raise

Prevention

When it happens

Trigger: Creating a Series/Frame from a sequence whose declared dtype maps to a base type with no constructor entry — e.g. passing pl.Unknown, pl.Null used incorrectly, an unregistered custom/extension dtype, or a DataTypeInstance of an exotic category to pl.Series(..., dtype=...) / df with_columns.

Common situations: Using a custom extension dtype that was never registered; library-internal mapping out of sync after a polars version change; passing pl.Null or opaque nested types where a concrete dtype is required.

Related errors


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

Appendix: source

Thrown at py-polars/src/polars/datatypes/constructor.py:75

        bytes: PySeries.new_binary,
        PyDecimal: PySeries.new_decimal,
    }


def polars_type_to_constructor(
    dtype: PolarsDataType,
) -> Callable[[str, Sequence[Any], bool], PySeries]:
    """Get the right PySeries constructor for the given Polars dtype."""
    # Special case for Array as it needs to pass the dtype argument on construction
    if isinstance(dtype, dt.Array):
        return functools.partial(PySeries.new_array, dtype=dtype)

    try:
        base_type = dtype.base_type()
        return _POLARS_TYPE_TO_CONSTRUCTOR[base_type]
    except KeyError:  # pragma: no cover
        msg = f"cannot construct PySeries for type {dtype!r}"
        raise ValueError(msg) from None


_NUMPY_TYPE_TO_CONSTRUCTOR = None


def _set_numpy_to_constructor() -> None:
    global _NUMPY_TYPE_TO_CONSTRUCTOR
    _NUMPY_TYPE_TO_CONSTRUCTOR = {
        np.float16: PySeries.new_f16,
        np.float32: PySeries.new_f32,
        np.float64: PySeries.new_f64,
        np.int8: PySeries.new_i8,
        np.int16: PySeries.new_i16,
        np.int32: PySeries.new_i32,
        np.int64: PySeries.new_i64,
        np.uint8: PySeries.new_u8,
        np.uint16: PySeries.new_u16,
        np.uint32: PySeries.new_u32,

View on GitHub (pinned to fe841f959e)