From dcf2c939576e2cd0679a682567987de9a1e8b5cf Mon Sep 17 00:00:00 2001 From: Ayamullah Khan Date: Mon, 19 Oct 2026 17:47:45 +0000 Subject: [PATCH] fix(resample): reject a non-finite to_grid rate to_grid guarded rate_hz with `<= 0.0`, so nan compared false and inf read as positive; both reached Fraction(rate_hz) in _grid_timestamps_ns and surfaced as "cannot convert NaN to integer ratio" and OverflowError instead of a rate error. Route the rate through require_finite_float from _field_guards first, keeping the existing non-positive branch and message unchanged. The parametrized test covers 0, a negative rate, nan, inf and -inf, asserting the message each one must produce. Removing the guard line fails the nan/inf/-inf rows (3 failed, 2 passed); restored, 5 pass. --- src/hflow/resample.py | 2 ++ tests/test_resample_derive.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/hflow/resample.py b/src/hflow/resample.py index 725654384..29242e656 100644 --- a/src/hflow/resample.py +++ b/src/hflow/resample.py @@ -28,6 +28,7 @@ import numpy as np +from hflow._field_guards import require_finite_float from hflow.format import NANOSECONDS_PER_SECOND if TYPE_CHECKING: @@ -238,6 +239,7 @@ def to_grid( pinned by ``hflow.format.RESAMPLE_POLICY_VERSION`` (see the module docstring). """ + rate_hz = require_finite_float(rate_hz, "rate_hz") if rate_hz <= 0.0: raise ValueError(f"rate_hz must be positive, got {rate_hz}") source_columns = _source_columns(channel, field) diff --git a/tests/test_resample_derive.py b/tests/test_resample_derive.py index 9fe877be0..2d48a5f18 100644 --- a/tests/test_resample_derive.py +++ b/tests/test_resample_derive.py @@ -208,9 +208,19 @@ def test_to_grid_rejects_span_shorter_than_one_step() -> None: to_grid(ramp_channel(), 0.01, policy="interpolate") -def test_to_grid_rejects_nonpositive_rate() -> None: - with pytest.raises(ValueError, match="rate_hz must be positive"): - to_grid(ramp_channel(), 0.0, policy="interpolate") +@pytest.mark.parametrize( + ("rate_hz", "message"), + [ + (0.0, "rate_hz must be positive"), + (-1.0, "rate_hz must be positive"), + (float("nan"), "rate_hz must be finite"), + (float("inf"), "rate_hz must be finite"), + (float("-inf"), "rate_hz must be finite"), + ], +) +def test_to_grid_requires_a_finite_positive_rate(rate_hz: float, message: str) -> None: + with pytest.raises(ValueError, match=message): + to_grid(ramp_channel(), rate_hz, policy="interpolate") def test_derived_series_validates_column_lengths() -> None: