diff --git a/py-polars/polars/__init__.py b/py-polars/polars/__init__.py index 9abe028cbe25..b0495b3ef1df 100644 --- a/py-polars/polars/__init__.py +++ b/py-polars/polars/__init__.py @@ -29,6 +29,7 @@ DURATION_DTYPES, FLOAT_DTYPES, INTEGER_DTYPES, + NESTED_DTYPES, NUMERIC_DTYPES, TEMPORAL_DTYPES, Array, @@ -253,6 +254,7 @@ "DURATION_DTYPES", "FLOAT_DTYPES", "INTEGER_DTYPES", + "NESTED_DTYPES", "NUMERIC_DTYPES", "TEMPORAL_DTYPES", # polars.type_aliases diff --git a/py-polars/polars/datatypes/__init__.py b/py-polars/polars/datatypes/__init__.py index 9c5136f8d5e6..4576282539c4 100644 --- a/py-polars/polars/datatypes/__init__.py +++ b/py-polars/polars/datatypes/__init__.py @@ -40,6 +40,7 @@ FLOAT_DTYPES, INTEGER_DTYPES, N_INFER_DEFAULT, + NESTED_DTYPES, NUMERIC_DTYPES, SIGNED_INTEGER_DTYPES, TEMPORAL_DTYPES, @@ -113,6 +114,7 @@ "DURATION_DTYPES", "FLOAT_DTYPES", "INTEGER_DTYPES", + "NESTED_DTYPES", "NUMERIC_DTYPES", "N_INFER_DEFAULT", "SIGNED_INTEGER_DTYPES", diff --git a/py-polars/polars/datatypes/classes.py b/py-polars/polars/datatypes/classes.py index 0520866d76a8..aa9d316c21d3 100644 --- a/py-polars/polars/datatypes/classes.py +++ b/py-polars/polars/datatypes/classes.py @@ -144,7 +144,21 @@ def is_not(self, other: PolarsDataType) -> bool: @classproperty def is_nested(self) -> bool: - """Check if this data type is nested.""" + """ + Check if this data type is nested. + + .. deprecated:: 0.19.10 + Use `dtype in pl.NESTED_DTYPES` instead. + + """ + from polars.utils.deprecation import issue_deprecation_warning + + message = ( + "`DataType.is_nested` is deprecated and will be removed in the next breaking release." + " It will be changed to a classmethod rather than a property." + " To silence this warning, use `dtype in pl.NESTED_DTYPES` instead." + ) + issue_deprecation_warning(message, version="0.19.10") return False @@ -220,7 +234,21 @@ class NestedType(DataType): @classproperty def is_nested(self) -> bool: - """Check if this data type is nested.""" + """ + Check if this data type is nested. + + .. deprecated:: 0.19.10 + Use `dtype in pl.NESTED_DTYPES` instead. + + """ + from polars.utils.deprecation import issue_deprecation_warning + + message = ( + "`DataType.is_nested` is deprecated and will be removed in the next breaking release." + " It will be changed to a classmethod rather than a property." + " To silence this warning, use `dtype in pl.NESTED_DTYPES` instead." + ) + issue_deprecation_warning(message, version="0.19.10") return True diff --git a/py-polars/polars/datatypes/constants.py b/py-polars/polars/datatypes/constants.py index a1654442ecc9..24219b7e15ba 100644 --- a/py-polars/polars/datatypes/constants.py +++ b/py-polars/polars/datatypes/constants.py @@ -14,6 +14,8 @@ Int16, Int32, Int64, + List, + Struct, Time, UInt8, UInt16, @@ -73,5 +75,7 @@ FLOAT_DTYPES | INTEGER_DTYPES | frozenset([Decimal]) ) +NESTED_DTYPES: frozenset[PolarsDataType] = DataTypeGroup([List, Struct]) + # number of rows to scan by default when inferring datatypes N_INFER_DEFAULT = 100 diff --git a/py-polars/polars/testing/asserts/series.py b/py-polars/polars/testing/asserts/series.py index 028c1cff6db7..e285af716d6c 100644 --- a/py-polars/polars/testing/asserts/series.py +++ b/py-polars/polars/testing/asserts/series.py @@ -3,6 +3,7 @@ from polars import functions as F from polars.datatypes import ( FLOAT_DTYPES, + NESTED_DTYPES, UNSIGNED_INTEGER_DTYPES, Categorical, List, @@ -139,7 +140,7 @@ def _assert_series_values_equal( unequal = unequal | left.is_nan() | right.is_nan() # check nested dtypes in separate function - if left.dtype.is_nested or right.dtype.is_nested: + if left.dtype in NESTED_DTYPES or right.dtype in NESTED_DTYPES: if _assert_series_nested( left=left.filter(unequal), right=right.filter(unequal), diff --git a/py-polars/tests/unit/datatypes/test_list.py b/py-polars/tests/unit/datatypes/test_list.py index abe5ec123780..a6651ef23098 100644 --- a/py-polars/tests/unit/datatypes/test_list.py +++ b/py-polars/tests/unit/datatypes/test_list.py @@ -43,7 +43,7 @@ def test_dtype() -> None: "dt": pl.List(pl.Date), "dtm": pl.List(pl.Datetime), } - assert all(tp.is_nested for tp in df.dtypes) + assert all(tp in pl.NESTED_DTYPES for tp in df.dtypes) assert df.schema["i"].inner == pl.Int8 # type: ignore[union-attr] assert df.rows() == [ ( @@ -69,17 +69,15 @@ def test_categorical() -> None: out = ( df.group_by(["a", "b"]) .agg( - [ - pl.col("c").count().alias("num_different_c"), - pl.col("c").alias("c_values"), - ] + pl.col("c").count().alias("num_different_c"), + pl.col("c").alias("c_values"), ) .filter(pl.col("num_different_c") >= 2) .to_series(3) ) assert out.inner_dtype == pl.Categorical - assert not out.inner_dtype.is_nested + assert out.inner_dtype not in pl.NESTED_DTYPES def test_cast_inner() -> None: @@ -565,3 +563,11 @@ def test_list_inner_cast_physical_11513() -> None: }, ) assert df.select(pl.col("struct").take(0)).to_dict(False) == {"struct": [[]]} + + +@pytest.mark.parametrize( + ("dtype", "expected"), [(pl.List, True), (pl.Struct, True), (pl.Utf8, False)] +) +def test_list_is_nested_deprecated(dtype: PolarsDataType, expected: bool) -> None: + with pytest.deprecated_call(): + assert dtype.is_nested is expected diff --git a/py-polars/tests/unit/datatypes/test_struct.py b/py-polars/tests/unit/datatypes/test_struct.py index b372be41f045..1bc4a7a4b4a8 100644 --- a/py-polars/tests/unit/datatypes/test_struct.py +++ b/py-polars/tests/unit/datatypes/test_struct.py @@ -152,7 +152,7 @@ def test_struct_unnest_multiple() -> None: # List input result = df_structs.unnest(["s1", "s2"]) assert_frame_equal(result, df) - assert all(tp.is_nested for tp in df_structs.dtypes) + assert all(tp in pl.NESTED_DTYPES for tp in df_structs.dtypes) # Positional input result = df_structs.unnest("s1", "s2")