pola-rs/polars · error

unsupported type {qualified_type_name(arg)!r} for {arg!r}

Error message

unsupported type {qualified_type_name(arg)!r} for {arg!r}

What it means

Raised in Series.__array_ufunc__ during argument collection: every input to the ufunc must be an int, float, numpy ndarray, or another Polars Series. Anything else - lists, strings, complex scalars, pandas objects, None - cannot be handed to the Rust kernel and is rejected with the argument's qualified type name.

Source

Thrown at py-polars/src/polars/series/series.py:1645

        s = self._s

        if method == "__call__":
            if ufunc.nout != 1:
                msg = "only ufuncs that return one 1D array are supported"
                raise NotImplementedError(msg)

            args: list[int | float | np.ndarray[Any, Any]] = []
            for arg in inputs:
                if isinstance(arg, (int, float, np.ndarray)):
                    args.append(arg)
                elif isinstance(arg, Series):
                    phys_arg = arg.to_physical()
                    if phys_arg._s.n_chunks() > 1:
                        phys_arg._s.rechunk(in_place=True)
                    args.append(phys_arg._s.to_numpy_view())  # type: ignore[arg-type]
                else:
                    msg = f"unsupported type {qualified_type_name(arg)!r} for {arg!r}"
                    raise TypeError(msg)

            # Get minimum dtype needed to be able to cast all input arguments to the
            # same dtype.
            dtype_char_minimum: str = np.result_type(*args).char

            # Get all possible output dtypes for ufunc.
            # Input dtypes and output dtypes seem to always match for ufunc.types,
            # so pick all the different output dtypes.
            dtypes_ufunc = [
                input_output_type[-1]
                for input_output_type in ufunc.types
                if supported_numpy_char_code(input_output_type[-1])
            ]

            # Get the first ufunc dtype from all possible ufunc dtypes for which
            # the input arguments can be safely cast to that ufunc dtype.
            for dtype_ufunc in dtypes_ufunc:
                if np.can_cast(dtype_char_minimum, dtype_ufunc):

View on GitHub (pinned to df599052da)

Solutions

  1. Convert the operand before the call: `np.add(s, np.array([1, 2, 3]))` or `np.add(s, pl.Series([1, 2, 3]))`.
  2. Use scalars directly where possible: `np.add(s, 3)`.
  3. Convert pandas objects: `np.add(s, pd_series.to_numpy())`.
  4. In generic dispatch code, pre-normalize args: lists -> np.asarray, pandas -> .to_numpy().

Example fix

// before
np.add(s, [1, 2, 3])  # TypeError: unsupported type 'list'

// after
np.add(s, np.array([1, 2, 3]))
# or
np.add(s, pl.Series([1, 2, 3]))
Defensive patterns

Strategy: type-guard

Validate before calling

def coerce_ufunc_arg(a):
    if isinstance(a, (int, float, np.ndarray, pl.Series)):
        return a
    return np.asarray(a)

args = [coerce_ufunc_arg(a) for a in args]

Type guard

def is_ufunc_arg_supported(a) -> bool:
    return isinstance(a, (int, float, np.ndarray, pl.Series))

Try / catch

try:
    out = np.add(s, other)
except TypeError as e:
    if 'unsupported type' not in str(e):
        raise
    out = np.add(s, np.asarray(other))

Prevention

When it happens

Trigger: `np.add(s, [1, 2, 3])` (python list operand), `np.multiply(s, 'x')`, `np.add(s, 1+2j)` (complex scalar is not int/float), `np.exp(s, out=None)`-style passing a pandas Series. Series operands are converted via to_physical() and rechunked first, so those pass.

Common situations: Passing raw python lists where a converted array was intended; mixing pandas and polars objects in one expression; complex-valued operands; leftover None sentinel arguments in generic numeric wrappers.

Related errors


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