Path: blob/main/py-polars/tests/unit/expr/test_literal.py
8424 views
from __future__ import annotations12from datetime import datetime, timezone3from typing import TYPE_CHECKING, Any4from zoneinfo import ZoneInfo56import pytest7from dateutil.tz import tzoffset89import polars as pl10from polars.testing import assert_frame_equal1112if TYPE_CHECKING:13from polars._typing import PolarsDataType141516def test_literal_scalar_list_18686() -> None:17df = pl.DataFrame({"column1": [1, 2], "column2": ["A", "B"]})18out = df.with_columns(lit1=pl.lit([]).cast(pl.List(pl.String)), lit2=pl.lit([]))1920assert out.to_dict(as_series=False) == {21"column1": [1, 2],22"column2": ["A", "B"],23"lit1": [[], []],24"lit2": [[], []],25}26assert out.schema == pl.Schema(27[28("column1", pl.Int64),29("column2", pl.String),30("lit1", pl.List(pl.String)),31("lit2", pl.List(pl.Null)),32]33)343536def test_literal_integer_20807() -> None:37for i in range(100):38value = 2**i39assert pl.select(pl.lit(value)).item() == value40assert pl.select(pl.lit(-value)).item() == -value41assert pl.select(pl.lit(value, dtype=pl.Int128)).item() == value42assert pl.select(pl.lit(-value, dtype=pl.Int128)).item() == -value434445@pytest.mark.parametrize(46("tz", "lit_dtype"),47[48(ZoneInfo("Asia/Kabul"), None),49(ZoneInfo("Asia/Kabul"), pl.Datetime("us", "Asia/Kabul")),50(ZoneInfo("Europe/Paris"), pl.Datetime("us", "Europe/Paris")),51(timezone.utc, pl.Datetime("us", "UTC")),52],53)54def test_literal_datetime_timezone(tz: Any, lit_dtype: pl.DataType | None) -> None:55expected_dtype = pl.Datetime("us", time_zone=str(tz))56value = datetime(2020, 1, 1, tzinfo=tz)5758df1 = pl.DataFrame({"dt": [value]})59df2 = pl.select(dt=pl.lit(value, dtype=lit_dtype))6061assert_frame_equal(df1, df2)62assert df1.schema["dt"] == expected_dtype63assert df1.item() == value646566@pytest.mark.parametrize(67("tz", "lit_dtype", "expected_item"),68[69(70# fixed offset from UTC71tzoffset(None, 16200),72None,73datetime(2019, 12, 31, 19, 30, tzinfo=timezone.utc),74),75(76# fixed offset from UTC77tzoffset("Kabul", 16200),78None,79datetime(2019, 12, 31, 19, 30, tzinfo=ZoneInfo("UTC")),80),81(82# fixed offset from UTC with matching timezone83tzoffset(None, 16200),84pl.Datetime("us", "Asia/Kabul"),85datetime(2020, 1, 1, tzinfo=ZoneInfo("Asia/Kabul")),86),87(88# fixed offset from UTC with matching timezone89tzoffset("Kabul", 16200),90pl.Datetime("us", "Asia/Kabul"),91datetime(2020, 1, 1, tzinfo=ZoneInfo("Asia/Kabul")),92),93],94)95def test_literal_datetime_timezone_utc_offset(96tz: Any, lit_dtype: pl.DataType | None, expected_item: datetime97) -> None:98overrides = {"schema_overrides": {"dt": lit_dtype}} if lit_dtype else {}99value = datetime(2020, 1, 1, tzinfo=tz)100101# validate both frame and lit constructors102df1 = pl.DataFrame({"dt": [value]}, **overrides) # type: ignore[arg-type]103df2 = pl.select(dt=pl.lit(value, dtype=lit_dtype))104105assert_frame_equal(df1, df2)106107expected_tz = "UTC" if lit_dtype is None else getattr(lit_dtype, "time_zone", None)108expected_dtype = pl.Datetime("us", time_zone=expected_tz)109110for df in (df1, df2):111assert df.schema["dt"] == expected_dtype112assert df.item() == expected_item113114115def test_literal_datetime_timezone_utc_error() -> None:116value = datetime(2020, 1, 1, tzinfo=tzoffset("Somewhere", offset=3600))117118with pytest.raises(119TypeError,120match=(121r"time zone of dtype \('Pacific/Galapagos'\) differs from"122r" time zone of value \(tzoffset\('Somewhere', 3600\)\)"123),124):125# the offset does not correspond to the offset of the declared timezone126pl.select(dt=pl.lit(value, dtype=pl.Datetime(time_zone="Pacific/Galapagos")))127128129def test_literal_object_25679() -> None:130df = pl.DataFrame(131data={"colx": [0, 0, 1, 2, None, 3, 3, None]},132schema={"colx": pl.Object},133)134obj_zero = pl.lit(0, dtype=pl.Object())135res = df.select(pl.col("colx").fill_null(obj_zero))136137assert res.schema == {"colx": pl.Object()}138assert res["colx"].to_list() == [0, 0, 1, 2, 0, 3, 3, 0]139140141@pytest.mark.parametrize(142("numerator", "divisor", "floordiv", "mod"),143[144(10, 3, 3, 1),145(10, 2, 5, 0),146(1, 2, 0, 1),147(0, 10, 0, 0),148(1, 0, None, None),149],150)151@pytest.mark.parametrize(152("numerator_dtype", "divisor_dtype"),153[154(x, y)155for x in [pl.Int8, pl.UInt8, None]156for y in [pl.Int8, pl.UInt8, None]157if x == y or x is None or y is None158],159)160def test_floordiv_mod(161numerator: int,162divisor: int,163floordiv: int | None,164mod: int | None,165numerator_dtype: PolarsDataType | None,166divisor_dtype: PolarsDataType | None,167) -> None:168assert_frame_equal(169pl.select(170pl.lit(numerator, dtype=numerator_dtype)171// pl.lit(divisor, dtype=divisor_dtype)172),173pl.DataFrame(174{"literal": [floordiv]},175schema={"literal": numerator_dtype or divisor_dtype or pl.Int32},176),177)178assert_frame_equal(179pl.select(180pl.lit(numerator, dtype=numerator_dtype)181% pl.lit(divisor, dtype=divisor_dtype)182),183pl.DataFrame(184{"literal": [mod]},185schema={"literal": numerator_dtype or divisor_dtype or pl.Int32},186),187)188189190