From fbf382da13160e0255b3f70c5dfb22dbf4f6240d Mon Sep 17 00:00:00 2001 From: Maarten Sebregts Date: Thu, 20 Aug 2026 16:17:28 +0200 Subject: [PATCH] Add checks for conduit filter order - It's not allowed to have a reducer after a repeater -> taking the last of a repeated message is not useful - It's not allowed to have a repeat filter after a pad filter -> it would repeat nil messages --- ymmsl/v0_2/model.py | 15 +++++++++++++++ ymmsl/v0_2/tests/test_model.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/ymmsl/v0_2/model.py b/ymmsl/v0_2/model.py index cc6edcd..51350bc 100644 --- a/ymmsl/v0_2/model.py +++ b/ymmsl/v0_2/model.py @@ -126,6 +126,21 @@ def __init__( self.__check_reference(self.sender) self.__check_reference(self.receiver) + # Check if filters are in the correct order: + err_msg = None + for i in range(len(self.filters) - 1): + pair = self.filters[i : i + 2] + if pair == [ConduitFilter.REPEAT, ConduitFilter.LAST]: + err_msg = "'repeat' filter must come after 'last'" + break + if pair == [ConduitFilter.PAD, ConduitFilter.LAST]: + err_msg = "'pad' filter must come after 'last'" + break + if pair == [ConduitFilter.PAD, ConduitFilter.REPEAT]: + err_msg = "'pad' filter must come after 'repeat'" + if err_msg is not None: + raise RuntimeError(f"Invalid conduit filter for {self}: {err_msg}.") + def __str__(self) -> str: """Return a string representation of the object.""" if not self.filters: diff --git a/ymmsl/v0_2/tests/test_model.py b/ymmsl/v0_2/tests/test_model.py index d4944a1..8f25484 100644 --- a/ymmsl/v0_2/tests/test_model.py +++ b/ymmsl/v0_2/tests/test_model.py @@ -21,6 +21,21 @@ def test_conduit_filter() -> None: assert ConduitFilter.PAD.is_repeater() +def test_conduit_order() -> None: + Conduit("a", "b", "last last") + Conduit("a", "b", "last pad") + Conduit("a", "b", "last repeat") + Conduit("a", "b", "repeat repeat") + Conduit("a", "b", "repeat pad") + Conduit("a", "b", "pad pad") + with pytest.raises(RuntimeError): + Conduit("a", "b", "repeat last") + with pytest.raises(RuntimeError): + Conduit("a", "b", "pad last") + with pytest.raises(RuntimeError): + Conduit("a", "b", "pad repeat") + + def test_conduit_access() -> None: conduit = Conduit("macro.out", "micro.in")