From a2897d8c4e5303e8e766a1d086dc7b796bfd1c63 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Fri, 17 Jul 2026 03:58:29 +0200 Subject: [PATCH 1/2] Reject masked update diagnostic integers --- src/pyrecest/filters/update_diagnostics.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pyrecest/filters/update_diagnostics.py b/src/pyrecest/filters/update_diagnostics.py index 7d88a66a8..f980b8179 100644 --- a/src/pyrecest/filters/update_diagnostics.py +++ b/src/pyrecest/filters/update_diagnostics.py @@ -7,6 +7,8 @@ from operator import index as operator_index from typing import Any +import numpy as np + _TEXT_SEQUENCE_TYPES = (str, bytes, bytearray) _ACTIVE_INDICES_MESSAGE = ( "active_measurement_indices must be a sequence of non-negative integers" @@ -129,6 +131,8 @@ def _normalize_metadata(metadata: Mapping[str, Any] | None) -> dict[str, Any]: def _as_nonnegative_integer(value: Any, name: str) -> int: message = f"{name} must be a non-negative integer" + if np.ma.isMaskedArray(value) and bool(np.any(np.ma.getmaskarray(value))): + raise ValueError(message) if _is_boolean_scalar(value): raise ValueError(message) try: From 4c744e46c88772dec783bcf9b3ace8bb68fa3503 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Fri, 17 Jul 2026 03:58:54 +0200 Subject: [PATCH 2/2] Add masked update diagnostic regressions --- .../test_update_diagnostics_validation.py | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/filters/test_update_diagnostics_validation.py b/tests/filters/test_update_diagnostics_validation.py index 51d6b5c54..0dcf3b239 100644 --- a/tests/filters/test_update_diagnostics_validation.py +++ b/tests/filters/test_update_diagnostics_validation.py @@ -20,6 +20,18 @@ def test_active_measurement_indices_reject_non_integer_values(): MeasurementUpdateDiagnostics(active_measurement_indices=(invalid_index,)) +def test_active_measurement_indices_reject_masked_integer_values(): + masked_indices = ( + np.ma.array(0, mask=True), + np.ma.array(7, mask=True), + np.ma.masked, + ) + + for masked_index in masked_indices: + with pytest.raises(ValueError, match="active_measurement_indices"): + MeasurementUpdateDiagnostics(active_measurement_indices=(masked_index,)) + + def test_active_measurement_indices_reject_non_sequence_values(): with pytest.raises(ValueError, match="active_measurement_indices"): MeasurementUpdateDiagnostics(active_measurement_indices=1) # type: ignore[arg-type] @@ -75,11 +87,22 @@ def test_measurement_count_rejects_non_integer_values(): MeasurementUpdateDiagnostics(measurement_count=invalid_count) +def test_measurement_count_rejects_masked_integer_values(): + for masked_count in (np.ma.array(0, mask=True), np.ma.array(3, mask=True)): + with pytest.raises(ValueError, match="measurement_count"): + MeasurementUpdateDiagnostics(measurement_count=masked_count) + + def test_diagnostics_accept_integer_like_numpy_scalars(): diagnostics = MeasurementUpdateDiagnostics( - active_measurement_indices=(0, np.int64(2), np.array(3)), - measurement_count=np.int64(4), + active_measurement_indices=( + 0, + np.ma.array(1, mask=False), + np.int64(2), + np.array(3), + ), + measurement_count=np.ma.array(4, mask=False), ) - assert diagnostics.active_measurement_indices == (0, 2, 3) + assert diagnostics.active_measurement_indices == (0, 1, 2, 3) assert diagnostics.measurement_count == 4