pola-rs/polars · error · TypeError

invalid input for shape

Error message

invalid input for shape: {shape!r}

What it means

Raised by a Polars datatype class (e.g. Array/List) when the `shape` argument passed to its constructor is not a valid shape tuple. Valid shapes are a single int or a tuple of ints; anything else (str, float, nested lists, empty tuple, None) is rejected. This is an eager constructor-level input validation.

Solutions

  1. Pass shape as a plain int or a tuple of positive ints, e.g. polars.Array(pl.Int64, (2, 3)).
  2. Convert config/parsed values: shape = tuple(int(s) for s in str_shape.split(',')) or int(value).
  3. Wrap a list as tuple(shape) before constructing the dtype.

Example fix

// before
pl.Array(pl.Int64, [2, 3])       # list
pl.Array(pl.Int64, '3')          # string
// after
pl.Array(pl.Int64, (2, 3))       # tuple of ints
pl.Array(pl.Int64, 3)            # single int
Defensive patterns

Strategy: validation

Validate before calling

def is_valid_shape(shape) -> bool:
    if isinstance(shape, int):
        return shape > 0
    return (
        isinstance(shape, tuple)
        and len(shape) > 0
        and all(isinstance(s, int) and s > 0 for s in shape)
    )

shape = tuple(shape) if isinstance(shape, list) else shape
if not is_valid_shape(shape):
    raise ValueError(f"bad dtype shape: {shape!r}")

Type guard

def is_shape(x: object) -> TypeGuard[tuple[int, ...]]:
    return isinstance(x, tuple) and len(x) > 0 and all(isinstance(i, int) for i in x)

Prevention

When it happens

Trigger: Calling polars.Array(dtype, shape) or a similar nested-type constructor with shape given as a string ('3'), a float (3.0), a list ([3]), None, a tuple of non-ints, or an empty tuple. Also triggered when shorthands like Array(Int64, (2, 'x')) are used.

Common situations: Hand-written schemas where shape came from a config string like '4' instead of int 4; building schemas programmatically and accidentally passing a list instead of tuple; parsing a dtype string back into a constructor call.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at py-polars/src/polars/datatypes/classes.py:1267

        inner_parsed = polars.datatypes.parse_into_dtype(inner)
        inner_shape = inner_parsed.shape if isinstance(inner_parsed, Array) else ()

        if isinstance(shape, int):
            self.inner = inner_parsed
            self.size = shape
            self.shape = (shape,) + inner_shape

        elif isinstance(shape, tuple) and isinstance(shape[0], int):  # type: ignore[redundant-expr]
            if len(shape) > 1:
                inner_parsed = Array(inner_parsed, shape[1:])

            self.inner = inner_parsed
            self.size = shape[0]
            self.shape = shape + inner_shape

        else:
            msg = f"invalid input for shape: {shape!r}"
            raise TypeError(msg)

    def __eq__(self, other: PolarsDataType) -> bool:  # type: ignore[override]
        # This equality check allows comparison of type classes and type instances.
        # If a parent type is not specific about its inner type, we infer it as equal:
        # > array[i64] == array[i64] -> True
        # > array[i64] == array[f32] -> False
        # > array[i64] == array      -> True

        # allow comparing object instances to class
        if type(other) is DataTypeClass and issubclass(other, Array):
            return True
        elif isinstance(other, Array):
            if self.shape != other.shape:
                return False
            else:
                return self.inner == other.inner
        else:
            return False

View on GitHub (pinned to fe841f959e)