Path: blob/main/py-polars/tests/unit/operations/namespaces/test_meta.py
6940 views
from __future__ import annotations12import re3from datetime import date, datetime, time, timedelta4from typing import TYPE_CHECKING, Any56import pytest78import polars as pl9import polars.selectors as cs10from polars.exceptions import ComputeError11from tests.unit.conftest import NUMERIC_DTYPES1213if TYPE_CHECKING:14from pathlib import Path151617def test_root_and_output_names() -> None:18e = pl.col("foo") * pl.col("bar")19assert e.meta.output_name() == "foo"20assert e.meta.root_names() == ["foo", "bar"]2122e = pl.col("foo").filter(bar=13)23assert e.meta.output_name() == "foo"24assert e.meta.root_names() == ["foo", "bar"]2526e = pl.sum("foo").over("groups")27assert e.meta.output_name() == "foo"28assert e.meta.root_names() == ["foo", "groups"]2930e = pl.sum("foo").slice(pl.len() - 10, pl.col("bar"))31assert e.meta.output_name() == "foo"32assert e.meta.root_names() == ["foo", "bar"]3334e = pl.len()35assert e.meta.output_name() == "len"3637with pytest.raises(38ComputeError,39match=re.escape(40"unable to find root column name for expr 'cs.all()' when calling 'output_name'"41),42):43pl.all().name.suffix("_").meta.output_name()4445assert (46pl.all().name.suffix("_").meta.output_name(raise_if_undetermined=False) is None47)484950def test_undo_aliases() -> None:51e = pl.col("foo").alias("bar")52assert e.meta.undo_aliases().meta == pl.col("foo")5354e = pl.col("foo").sum().over("bar")55assert e.name.keep().meta.undo_aliases().meta == e5657e.alias("bar").alias("foo")58assert e.meta.undo_aliases().meta == e59assert e.name.suffix("ham").meta.undo_aliases().meta == e606162def test_meta_has_multiple_outputs() -> None:63e = pl.col(["a", "b"]).name.suffix("_foo")64assert e.meta.has_multiple_outputs()656667def test_is_column() -> None:68e = pl.col("foo")69assert e.meta.is_column()7071e = pl.col("foo").alias("bar")72assert not e.meta.is_column()7374e = pl.col("foo") * pl.col("bar")75assert not e.meta.is_column()767778@pytest.mark.parametrize(79("expr", "is_column_selection"),80[81# columns82(pl.col("foo"), True),83(pl.col("foo", "bar"), True),84(pl.col(NUMERIC_DTYPES), True),85# column expressions86(pl.col("foo") + 100, False),87(pl.col("foo").floordiv(10), False),88(pl.col("foo") * pl.col("bar"), False),89# selectors / expressions90(cs.numeric() * 100, False),91(cs.temporal() - cs.time(), True),92(cs.numeric().exclude("value"), True),93((cs.temporal() - cs.time()).exclude("dt"), True),94# top-level selection funcs95(pl.nth(2), True),96(pl.first(), True),97(pl.last(), True),98],99)100def test_is_column_selection(101expr: pl.Expr,102is_column_selection: bool,103) -> None:104if is_column_selection:105assert expr.meta.is_column_selection()106assert expr.meta.is_column_selection(allow_aliasing=True)107expr = (108expr.name.suffix("!")109if expr.meta.has_multiple_outputs()110else expr.alias("!")111)112assert not expr.meta.is_column_selection()113assert expr.meta.is_column_selection(allow_aliasing=True)114else:115assert not expr.meta.is_column_selection()116117118@pytest.mark.parametrize(119"value",120[121None,1221234,123567.89,124float("inf"),125date.today(),126datetime.now(),127time(10, 30, 45),128timedelta(hours=-24),129["x", "y", "z"],130pl.Series([None, None]),131[[10, 20], [30, 40]],132"this is the way",133],134)135def test_is_literal(value: Any) -> None:136e = pl.lit(value)137assert e.meta.is_literal()138139e = pl.lit(value).alias("foo")140assert not e.meta.is_literal()141142e = pl.lit(value).alias("foo")143assert e.meta.is_literal(allow_aliasing=True)144145146def test_meta_is_regex_projection() -> None:147e = pl.col("^.*$").name.suffix("_foo")148assert e.meta.is_regex_projection()149assert e.meta.has_multiple_outputs()150151e = pl.col("^.*") # no trailing '$'152assert not e.meta.is_regex_projection()153assert not e.meta.has_multiple_outputs()154assert e.meta.is_column()155156157def test_meta_tree_format(namespace_files_path: Path) -> None:158with (namespace_files_path / "test_tree_fmt.txt").open("r", encoding="utf-8") as f:159test_sets = f.read().split("---")160for test_set in test_sets:161expression = test_set.strip().split("\n")[0]162tree_fmt = "\n".join(test_set.strip().split("\n")[1:])163e = eval(expression)164result = e.meta.tree_format(return_as_string=True)165result = "\n".join(s.rstrip() for s in result.split("\n"))166assert result.strip() == tree_fmt.strip()167168169def test_meta_show_graph(namespace_files_path: Path) -> None:170e = (pl.col("foo") * pl.col("bar")).sum().over(pl.col("ham")) / 2171dot = e.meta.show_graph(show=False, raw_output=True)172assert dot is not None173assert len(dot) > 0174# Don't check output contents since this creates a maintenance burden175# Assume output check in test_meta_tree_format is enough176177178def test_literal_output_name() -> None:179e = pl.lit(1)180assert e.meta.output_name() == "literal"181182e = pl.lit(pl.Series("abc", [1, 2, 3]))183assert e.meta.output_name() == "abc"184185e = pl.lit(pl.Series([1, 2, 3]))186assert e.meta.output_name() == ""187188189def test_struct_field_output_name_24003() -> None:190assert pl.col("ball").struct.field("radius").meta.output_name() == "radius"191192193def test_selector_by_name_single() -> None:194assert cs.by_name("foo").meta.output_name() == "foo"195196197def test_selector_by_name_multiple() -> None:198with pytest.raises(ComputeError):199cs.by_name(["foo", "bar"]).meta.output_name()200201202