diff --git a/narwhals/_plan/expressions/selectors.py b/narwhals/_plan/expressions/selectors.py index c741ad5632..48079c4388 100644 --- a/narwhals/_plan/expressions/selectors.py +++ b/narwhals/_plan/expressions/selectors.py @@ -329,6 +329,9 @@ def _matches(self, dtype: IntoDType) -> bool: class Enum(DTypeSelector, dtype=_dtypes.Enum): ... +class Decimal(DTypeSelector, dtype=_dtypes.Decimal): ... + + class Float(DTypeSelector, dtype=FloatType): ... diff --git a/narwhals/_plan/selectors.py b/narwhals/_plan/selectors.py index 6dca244806..045418df11 100644 --- a/narwhals/_plan/selectors.py +++ b/narwhals/_plan/selectors.py @@ -33,6 +33,7 @@ "by_name", "categorical", "datetime", + "decimal", "duration", "empty", "enum", @@ -231,6 +232,10 @@ def enum() -> Selector: return s_ir.Enum().to_selector_ir().to_narwhals() +def decimal() -> Selector: + return s_ir.Decimal().to_selector_ir().to_narwhals() + + def first() -> Selector: return s_ir.ByIndex.from_index(0).to_selector_ir().to_narwhals() @@ -284,4 +289,5 @@ def temporal() -> Selector: _dtypes.Array: array, _dtypes.List: list, _dtypes.Struct: struct, + _dtypes.Decimal: decimal, } diff --git a/tests/plan/selectors_test.py b/tests/plan/selectors_test.py index a9565521f8..232bef93cf 100644 --- a/tests/plan/selectors_test.py +++ b/tests/plan/selectors_test.py @@ -691,6 +691,17 @@ def test_selector_struct() -> None: df.assert_selects(~ncs.struct(), "a", "b", "d", "f", "g") +def test_selector_decimal(schema_mixed: nw.Schema) -> None: + df = Frame(schema_mixed) + df.assert_selects(ncs.decimal()) + df = df.from_mapping( + {"zz0": nw.Float64(), "zz1": nw.Decimal(38, 5), "zz2": nw.Decimal()} + ) + df.assert_selects(ncs.numeric(), "zz0", "zz1", "zz2") + df.assert_selects(ncs.decimal(), "zz1", "zz2") + df.assert_selects(~ncs.decimal(), "zz0") + + def test_selector_matches_22816() -> None: df = Frame.from_names("ham", "hamburger", "foo", "bar") df.assert_selects(ncs.matches(r"^ham.*$"), "ham", "hamburger")