From 79c4290ac5d0c2d75dfce543f51bece2745ae9d1 Mon Sep 17 00:00:00 2001 From: nkgotcode Date: Wed, 3 Jun 2026 01:00:53 -0500 Subject: [PATCH] Fix dataframe filter rows list payload parsing --- .../ui/_impl/dataframes/transforms/types.py | 10 +++++- .../ui/_impl/dataframes/test_dataframe.py | 31 +++++++++++++++++++ .../ui/_impl/dataframes/test_transforms.py | 22 +++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/marimo/_plugins/ui/_impl/dataframes/transforms/types.py b/marimo/_plugins/ui/_impl/dataframes/transforms/types.py index 7ae324f0133..c08b2f43c69 100644 --- a/marimo/_plugins/ui/_impl/dataframes/transforms/types.py +++ b/marimo/_plugins/ui/_impl/dataframes/transforms/types.py @@ -207,7 +207,15 @@ class SortColumnTransform: class FilterRowsTransform: type: Literal[TransformType.FILTER_ROWS] operation: Literal["keep_rows", "remove_rows"] - where: FilterGroup + where: FilterGroup | list[FilterCondition | FilterGroup] + + def __post_init__(self) -> None: + if isinstance(self.where, list): + object.__setattr__( + self, + "where", + FilterGroup(children=tuple(self.where)), + ) @dataclass diff --git a/tests/_plugins/ui/_impl/dataframes/test_dataframe.py b/tests/_plugins/ui/_impl/dataframes/test_dataframe.py index da83e25dc87..7c5ba9e6809 100644 --- a/tests/_plugins/ui/_impl/dataframes/test_dataframe.py +++ b/tests/_plugins/ui/_impl/dataframes/test_dataframe.py @@ -37,6 +37,23 @@ HAS_IBIS = DependencyManager.ibis.has() HAS_POLARS = DependencyManager.polars.has() +ROW_FILTER_LIST_WHERE_VALUE = { + "transforms": [ + { + "type": "filter_rows", + "operation": "keep_rows", + "where": [ + { + "type": "condition", + "column_id": "sepal_length", + "operator": ">", + "value": 5, + }, + ], + }, + ] +} + if TYPE_CHECKING: from narwhals.stable.v2.typing import IntoDataFrame, IntoLazyFrame @@ -72,6 +89,20 @@ def test_dataframe_supports_dataframe_backends(df: Any) -> None: # original native type for each supported dataframe backend. assert type(subject.value) is type(df) + @staticmethod + def test_dataframe_form_accepts_filter_rows_list_where() -> None: + df = pd.DataFrame( + { + "sepal_length": [4.9, 5.1, 6.2], + "species": ["setosa", "setosa", "virginica"], + } + ) + subject = ui.dataframe(df).form() + + subject._convert_value(ROW_FILTER_LIST_WHERE_VALUE) + + assert subject.element._error is None + @staticmethod @pytest.mark.parametrize( "df", diff --git a/tests/_plugins/ui/_impl/dataframes/test_transforms.py b/tests/_plugins/ui/_impl/dataframes/test_transforms.py index 1e310cb6e1a..707799680a2 100644 --- a/tests/_plugins/ui/_impl/dataframes/test_transforms.py +++ b/tests/_plugins/ui/_impl/dataframes/test_transforms.py @@ -45,6 +45,28 @@ def test_parse_transforms() -> None: assert isinstance(result, Transformations) +def test_parse_filter_rows_transform_with_legacy_list_where() -> None: + value = { + "transforms": [ + { + "type": "filter_rows", + "operation": "keep_rows", + "where": [ + { + "type": "condition", + "column_id": "sepal_length", + "operator": ">", + "value": 5, + }, + ], + }, + ] + } + + result = parse_raw(value, Transformations) + assert isinstance(result, Transformations) + + def test_parse_transforms_with_in_operator() -> None: def create_transform(operator: str): return {