Repository: pola-rs/polars
File: py-polars/tests/unit/datatypes/test_duration.py (Python)

Code before:
    total_units_fn: Callable[[pl.Series], pl.Series],
    total_units_scale: int,
    s: pl.Series,
) -> None:
    expected = s.cast(pl.Float64) * time_unit_scale / total_units_scale

    actual = total_units_fn(
        pl.select(pl.duration(**{time_unit_kw: s}, time_unit=time_unit).alias("a"))  # type: ignore[arg-type]
        .to_series()
        .dt,
    )
    assert_series_equal(actual, expected)

    # Check scalar case separately, since it's handled separately
    actual = total_units_fn(
        pl.select(pl.duration(**{time_unit_kw: s[0]}, time_unit=time_unit).alias("a"))  # type: ignore[arg-type]
        .to_series()
        .dt,
    )
    assert_series_equal(actual, expected.slice(0, 1))


def scalar_i64_overflow() -> None:
    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="conversion from `u64` to `i64` failed in column '' for 1 out of 1 values: \\[9223372036854775808]",
    ):
        pl.select(pl.duration(nanoseconds=2**63))

    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="conversion from `i128` to `i64` failed in column 'scalar' for 1 out of 1 values: \\[18446744073709551616]",
    ):
        pl.select(pl.duration(nanoseconds=2**64))

    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="conversion from `i128` to `i64` failed in column '' for 1 out of 1 values: \\[-9223372036854775809]",
    ):
        pl.select(pl.duration(nanoseconds=-(2**63) - 1))


Review comment (suggestion):
Can you make the match more generic than test such a specific pattern? For example any `InvalidOperationError` with that integer should be sufficient.

If every test tested the error message with such specificity then changing an error message would become a massive undertaking. We don't generally provide any stability guarantee for error messages anyway.

Code after:
    total_units_fn: Callable[[pl.Series], pl.Series],
    total_units_scale: int,
    s: pl.Series,
) -> None:
    expected = s.cast(pl.Float64) * time_unit_scale / total_units_scale

    actual = total_units_fn(
        pl.select(pl.duration(**{time_unit_kw: s}, time_unit=time_unit).alias("a"))  # type: ignore[arg-type]
        .to_series()
        .dt,
    )
    assert_series_equal(actual, expected)

    # Check scalar case separately, since it's handled separately
    actual = total_units_fn(
        pl.select(pl.duration(**{time_unit_kw: s[0]}, time_unit=time_unit).alias("a"))  # type: ignore[arg-type]
        .to_series()
        .dt,
    )
    assert_series_equal(actual, expected.slice(0, 1))


def test_scalar_i64_overflow() -> None:
    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="9223372036854775808",
    ):
        pl.select(pl.duration(nanoseconds=2**63))

    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="18446744073709551616",
    ):
        pl.select(pl.duration(nanoseconds=2**64))

    with pytest.raises(
        pl.exceptions.InvalidOperationError,
        match="-9223372036854775809",
    ):
        pl.select(pl.duration(nanoseconds=-(2**63) - 1))