Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crates/polars-core/src/datatypes/dtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ pub trait MetaDataExt: IntoMetadata {
}

fn pl_categorical_metadata(&self) -> Option<&str> {
// We ignore DTYPE_CATEGORICAL_LEGACY here, as we already map all
// string-typed arrow dictionaries to the global Categories, and the
// legacy metadata format only specifies the now-removed physical
// ordering parameter.
Some(
self.into_metadata_ref()
.get(DTYPE_CATEGORICAL_NEW)?
Expand Down Expand Up @@ -533,8 +537,6 @@ impl DataType {
use DataType::*;
match self {
Binary | String => true,
#[cfg(feature = "dtype-categorical")]
Categorical(_, _) | Enum(_, _) => true, // TODO @ cat-rework: is this right?
List(inner) => inner.contains_views(),
#[cfg(feature = "dtype-array")]
Array(inner, _) => inner.contains_views(),
Expand Down
25 changes: 6 additions & 19 deletions crates/polars-plan/src/plans/conversion/dsl_to_ir/expr_to_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,25 +350,12 @@ pub(super) fn to_aexpr_impl(
match variant {
EvalVariant::List => {
for (_, e) in ArenaExprIter::iter(&&*arena, evaluation) {
match e {
#[cfg(feature = "dtype-categorical")]
AExpr::Cast {
dtype: DataType::Categorical(_, _) | DataType::Enum(_, _),
..
} => {
// TODO @ cat-rework: why not?
polars_bail!(
ComputeError: "casting to categorical not allowed in `list.eval`"
)
},
AExpr::Column(name) => {
polars_ensure!(
name.is_empty(),
ComputeError:
"named columns are not allowed in `list.eval`; consider using `element` or `col(\"\")`"
);
},
_ => {},
if let AExpr::Column(name) = e {
polars_ensure!(
name.is_empty(),
ComputeError:
"named columns are not allowed in `list.eval`; consider using `element` or `col(\"\")`"
);
}
}
},
Expand Down
18 changes: 0 additions & 18 deletions py-polars/tests/unit/datatypes/test_categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

import polars as pl
from polars import StringCache
from polars.exceptions import (
ComputeError,
)
from polars.testing import assert_frame_equal, assert_series_equal
from tests.unit.conftest import with_string_cache_if_auto_streaming

Expand Down Expand Up @@ -425,21 +422,6 @@ def test_categorical_in_struct_nulls() -> None:
assert s[2] == {"job": "waiter", "count": 1}


@pytest.mark.usefixtures("test_global_and_local")
def test_cast_inner_categorical() -> None:
dtype = pl.List(pl.Categorical)
out = pl.Series("foo", [["a"], ["a", "b"]]).cast(dtype)
assert out.dtype == dtype
assert out.to_list() == [["a"], ["a", "b"]]

with pytest.raises(
ComputeError, match=r"casting to categorical not allowed in `list.eval`"
):
pl.Series("foo", [["a", "b"], ["a", "b"]]).list.eval(
pl.element().cast(pl.Categorical)
)


@pytest.mark.slow
def test_stringcache() -> None:
N = 1_500
Expand Down
10 changes: 10 additions & 0 deletions py-polars/tests/unit/operations/namespaces/list/test_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ def test_list_eval_categorical() -> None:
)


def test_list_eval_cast_categorical() -> None:
df = pl.DataFrame({"test": [["a", None], ["c"], [], ["a", "b", "c"]]})
expected = pl.DataFrame(
{"test": [["a", None], ["c"], [], ["a", "b", "c"]]},
schema={"test": pl.List(pl.Categorical)},
)
result = df.select(pl.col("test").list.eval(pl.element().cast(pl.Categorical)))
assert_frame_equal(result, expected)


def test_list_eval_type_coercion() -> None:
last_non_null_value = pl.element().fill_null(3).last()
df = pl.DataFrame({"array_cols": [[1, None]]})
Expand Down
Loading