pola-rs/polars · error · TypeError
dtype '{dtype}' is a BaseExtension class, it should be an in
Error message
dtype '{dtype}' is a BaseExtension class, it should be an instance What it means
Raised by polars.lit when the dtype argument is a BaseExtension subclass (an extension-dtype class) instead of an instance of it. Extension dtypes carry parameters (like the extension type they wrap), so polars must receive an instantiated dtype; classes are only accepted for built-in datatypes.
Source
Thrown at py-polars/src/polars/functions/lit.py:89
>>> pl.lit(datetime(2023, 3, 31, 10, 30, 45)) # doctest: +IGNORE_RESULT
Literal list/Series data (1D):
>>> pl.lit([1, 2, 3]) # doctest: +SKIP
>>> pl.lit(pl.Series("x", [1, 2, 3])) # doctest: +IGNORE_RESULT
Literal list/Series data (2D):
>>> pl.lit([[1, 2], [3, 4]]) # doctest: +SKIP
>>> pl.lit(pl.Series("y", [[1, 2], [3, 4]])) # doctest: +IGNORE_RESULT
"""
time_unit: TimeUnit
if isinstance(dtype, BaseExtension):
return lit(value, dtype.ext_storage()).ext.to(dtype)
elif isinstance(dtype, type) and issubclass(dtype, BaseExtension):
msg = f"dtype '{dtype}' is a BaseExtension class, it should be an instance"
raise TypeError(msg)
elif isinstance(dtype, DataTypeExpr):
return lit(value).cast(dtype)
elif dtype == Object:
value_s = pl.Series("literal", [value], dtype=dtype)
return wrap_expr(plr.lit(value_s._s, allow_object, is_scalar=True))
if isinstance(value, datetime):
if dtype == Date:
return wrap_expr(plr.lit(value.date(), allow_object=False, is_scalar=True))
# parse time unit
if dtype is not None and (tu := getattr(dtype, "time_unit", "us")) is not None:
tu = cast("TimeUnit", tu)
time_unit = tu
else:
time_unit = "us"
# parse time zoneView on GitHub (pinned to df599052da)
Solutions
- Instantiate the extension dtype: pl.lit(value, dtype=MyExtensionDType())
- If the extension wraps another storage type, you can also call pl.lit(value, dtype=MyExtensionDType().ext_storage()).ext.to(MyExtensionDType()) which is exactly what the instance path does
- Check for stray isinstance(dtype, type) in a wrapper/linter if dtype flows in from configuration
Example fix
// before pl.lit(value, dtype=MyExtensionDType) // after pl.lit(value, dtype=MyExtensionDType())
Defensive patterns
Strategy: type-guard
Validate before calling
from polars.datatypes import BaseExtension
if isinstance(dtype, type) and issubclass(dtype, BaseExtension):
dtype = dtype() # instantiate before calling pl.lit Type guard
def is_extension_dtype_instance(d) -> bool:
return isinstance(d, BaseExtension) Try / catch
try:
e = pl.lit(value, dtype=dtype)
except TypeError:
e = pl.lit(value, dtype=dtype()) # retry with an instance Prevention
- Always instantiate extension dtypes: MyExtDType()
- Lint for pl.lit(..., dtype=SomeClass) where SomeClass is not a built-in polars dtype
When it happens
Trigger: Writing pl.lit(value, dtype=MyExtensionDtype) (class, no parentheses) where MyExtensionDtype subclasses BaseExtension; passing the class when building a literal for a custom extension dtype registered via the plugin system.
Common situations: Authoring a polars extension-dtype plugin and mirroring the habitual pl.lit(x, dtype=pl.Int64) style where a class is fine; refactoring code that previously used only built-in dtypes; copy-pasting type annotations (classes) into runtime calls.
Related errors
- expected `on` to be str or Expr, got {qualified_type_name(on
- expected `left_on` to be str or Expr, got {qualified_type_na
- expected `right_on` to be str or Expr, got {qualified_type_n
- expected `by_predicate` to be an expression, got {qualified_
- method must be one of {{'pearson', 'spearman'}}, got {method
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/89985e7be6cf9c6d.
Report an issue: GitHub.