pola-rs/polars · error · TypeError

Enum categories must be strings;

Error message

Enum categories must be strings; `{enum_type_name}` values are integers

What it means

pl.Enum can be constructed from a Python enum.Enum class, but only if all values are strings. Flag and IntEnum subclasses have integer values, which cannot back a string Enum, so a TypeError naming the offending enum class is raised.

Solutions

  1. Define a separate str-based enum (class inherits from str, enum.Enum) for Polars categories
  2. Pass the string values explicitly as a list or Series instead of the enum class
  3. Convert values with [str(v.value) for v in MyEnum] and pass that list

Example fix

// before
class Color(enum.IntEnum):
    RED = 1
pl.Enum(Color)
// after
class Color(str, enum.Enum):
    RED = 'red'
pl.Enum(Color)
Defensive patterns

Strategy: validation

Validate before calling

import enum, inspect
if inspect.isclass(categories) and issubclass(categories, enum.Enum):
    if issubclass(categories, (enum.Flag, enum.IntEnum)):
        raise TypeError('use a str-based enum for pl.Enum categories')

Type guard

def is_str_enum(cls) -> bool:
    return inspect.isclass(cls) and issubclass(cls, enum.Enum) \
        and not issubclass(cls, (enum.IntEnum, enum.Flag)) \
        and all(isinstance(v.value, str) for v in cls)

Try / catch

try:
    dtype = pl.Enum(my_enum)
except TypeError as e:
    dtype = pl.Enum([str(v.value) for v in my_enum])

Prevention

When it happens

Trigger: pl.Enum(MyIntEnum) where MyIntEnum subclasses enum.IntEnum; pl.Enum(MyFlags) where MyFlags subclasses enum.Flag; pl.Enum of an enum inheriting IntFlag.

Common situations: Reusing existing application enums (status codes, permissions) defined as IntEnum directly as Polars Enum categories.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


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

Appendix: source

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

    >>> pl.Enum(["north", "south", "east", "west"])
    Enum(categories=['north', 'south', 'east', 'west'])

    Initialise from an existing Python enumeration:

    >>> from http import HTTPMethod
    >>> pl.Enum(HTTPMethod)
    Enum(categories=['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'])
    """  # noqa: W505

    categories: Series

    def __init__(self, categories: Series | Iterable[str] | type[enum.Enum]) -> None:
        if isclass(categories) and issubclass(categories, enum.Enum):
            for enum_subclass in (enum.Flag, enum.IntEnum):
                if issubclass(categories, enum_subclass):
                    enum_type_name = categories.__name__
                    msg = f"Enum categories must be strings; `{enum_type_name}` values are integers"
                    raise TypeError(msg)

            enum_values = [
                getattr(v, "value", v) for v in categories.__members__.values()
            ]
            categories = pl.Series(values=enum_values)
        elif not isinstance(categories, pl.Series):
            categories = pl.Series(values=categories)

        if categories.is_empty():
            self.categories = pl.Series(name="category", dtype=String)
            return

        if categories.has_nulls():
            msg = "Enum categories must not contain null values"
            raise TypeError(msg)

        if (dtype := categories.dtype) != String:
            msg = f"Enum categories must be strings; found data of type {dtype}"

View on GitHub (pinned to fe841f959e)