pola-rs/polars · error · ValueError

`separator` must be a single character; found {separator!r}

Error message

`separator` must be a single character; found {separator!r}

What it means

`pl.Config.set_decimal_separator(sep)` accepts a single-character string (e.g. ',' or '.'), a bool, or None. Any string whose length is not exactly 1 — multi-character sequences like ', ' or '.,', and the empty string '' — raises ValueError before the setting reaches the Rust core.

Source

Thrown at py-polars/src/polars/config.py:651

        ...     thousands_separator=".",
        ...     decimal_separator=",",
        ...     float_precision=3,
        ... ):
        ...     print(df)
        shape: (3, 1)
        ┌───────────────┐
        │             v │
        │           --- │
        │           f64 │
        ╞═══════════════╡
        │     9.876,543 │
        │ 1.010.101,000 │
        │  -123.456,780 │
        └───────────────┘
        """
        if isinstance(separator, str) and len(separator) != 1:
            msg = f"`separator` must be a single character; found {separator!r}"
            raise ValueError(msg)
        plr.set_decimal_separator(sep=separator)
        return cls

    @classmethod
    def set_thousands_separator(
        cls, separator: str | bool | None = None
    ) -> type[Config]:
        """
        Set the thousands grouping separator character.

        Parameters
        ----------
        separator : str, bool
            Set True to use the default "," (thousands) and "." (decimal) separators.
            Can also set a custom char, or set ``None`` to omit the separator.

        See Also
        --------

View on GitHub (pinned to 68506541d2)

Solutions

  1. Pass exactly one character: `pl.Config.set_decimal_separator(',')`.
  2. For full locale-style formatting, pair it: `pl.Config.set_thousands_separator('.')` after setting the decimal separator.
  3. Pass None (or a bool) to reset — these bypass the single-character check.

Example fix

# before
pl.Config.set_decimal_separator(", ")  # ValueError: `separator` must be a single character

# after
pl.Config.set_decimal_separator(",")
pl.Config.set_thousands_separator(".")
Defensive patterns

Strategy: validation

Validate before calling

def set_decimal(sep: str | bool | None) -> None:
    if isinstance(sep, str) and len(sep) != 1:
        raise ValueError(f"decimal separator must be a single character, got {sep!r}")
    pl.Config.set_decimal_separator(sep)

Type guard

def is_valid_separator(sep: object) -> bool:
    return sep is None or isinstance(sep, bool) or (isinstance(sep, str) and len(sep) == 1)

Prevention

When it happens

Trigger: `pl.Config.set_decimal_separator(', ')` (trailing space) or `set_decimal_separator('.,')`; also `set_decimal_separator('')` fails because an empty string has length 0.

Common situations: Configuring European-style number display ('1.234,50') and passing a two-character separator or a copy-pasted separator with whitespace.

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@68506541d2 (2026-08-19). Data as JSON: /api/errors/c79c3f4fee241be1. Report an issue: GitHub.