pola-rs/polars · error · AttributeError

{type(self).__name__!r} object has no attribute {name!r}

Error message

{type(self).__name__!r} object has no attribute {name!r}

What it means

This is the __getattr__ generated by polars.series.utils (used to build Series namespaces like str, dt, cat): when an attribute is not found on the Series object and no original __getattr__ handles it, Polars raises AttributeError with a helpful message. It is the standard Python 'attribute not found' error surfaced through a dynamically-constructed accessor chain.

Source

Thrown at py-polars/src/polars/series/utils.py:101

    """
    original_getattr = getattr(cls, "__getattr__", None)

    def __getattr__(self: Any, name: str) -> Any:
        # note: a dummy Expr suffices; we only want the namespace's __getattr__
        expr: Any = pl.Expr()
        expr._pyexpr = None
        if namespace is not None:
            expr = getattr(expr, namespace)
        try:
            return expr.__getattr__(name)
        except AttributeRemovedError:
            raise
        except AttributeError:
            if original_getattr is not None:
                return original_getattr(self, name)
            else:
                msg = f"{type(self).__name__!r} object has no attribute {name!r}"
                raise AttributeError(msg, name=name, obj=self) from None

    return __getattr__


def _expr_lookup(namespace: str | None) -> set[tuple[str | None, str, tuple[str, ...]]]:
    """Create lookup of potential Expr methods (in the given namespace)."""
    # dummy Expr object that we can introspect
    expr = pl.Expr()
    expr._pyexpr = None  # type: ignore[assignment]

    # optional indirection to "expr.str", "expr.dt", etc
    if namespace is not None:
        expr = getattr(expr, namespace)

    lookup = set()
    for name in dir(expr):
        if not name.startswith("_") or name == "__getattr__":
            try:

View on GitHub (pinned to 5d8ebabf11)

Solutions

  1. Check the misspelling against the Polars API docs for the relevant namespace (str/dt/cat/list)
  2. Verify the Series dtype matches the namespace you're calling (use s.dtype; cast with .cast(pl.Utf8) etc. if needed)
  3. If the method exists only on Expr, convert: pl.select(F.lit(s).<method>()) or use the equivalent Series-level API
  4. Check the Polars changelog if the method was renamed/moved in an upgrade

Example fix

# before
s.str.lowercse()

# after
s.str.to_lowercase()
Defensive patterns

Strategy: validation

Validate before calling

# before calling a namespace method, confirm it exists
assert hasattr(s.str, 'to_lowercase'), 'method missing on str namespace'

Type guard

from polars import Series

def has_namespace(s: Series, ns: str) -> bool:
    return {pl.String: 'str', pl.Datetime: 'dt', pl.Categorical: 'cat'}.get(s.dtype, None) == ns

Try / catch

try:
    out = s.str.to_lowercase()
except AttributeError as e:
    raise ValueError(f"bad Series operation on dtype {s.dtype}: {e}") from e

Prevention

When it happens

Trigger: Accessing any nonexistent attribute or misspelled method on a Series, e.g. s.str.lowercse(), s.dt.datetrunc('1d'), or an attribute that only exists on a different dtype namespace (s.cat on a non-Categorical series).

Common situations: Typos in chained expressions; calling Expr-only methods on Series (or vice versa); using namespace methods on the wrong dtype (str methods on numeric series); version changes that renamed/moved Series methods.

Related errors


AI-assisted analysis of pola-rs/polars@5d8ebabf11 (2026-08-28). Data as JSON: /api/errors/83f9fe32bba9b96d. Report an issue: GitHub.