diff --git a/killswitch.py b/killswitch.py index c89d7ace..7863a388 100644 --- a/killswitch.py +++ b/killswitch.py @@ -277,6 +277,25 @@ class KillSwitchSet: log.info('Rules applied successfully, allowing execution to continue') return False, new_data + def check_multiple_killswitches(self, data: UPDATABLE_DATA, *names: str, log=logger, version=_current_version): + """ + Check multiple killswitches in order. + + Note that the names are applied in the order passed, and that the first true + return from check_killswitch causes this to return + + :param data: the data to update + :param log: the logger to use, defaults to the standard EDMC main logger + :return: A tuple of bool and updated data, where the bool is true when the caller _should_ halt processing + """ + for name in names: + should_return, data = self.check_killswitch(name=name, data=data, log=log, version=version) + + if should_return: + return True, data + + return False, data + def __str__(self) -> str: """Return a string representation of KillSwitchSet.""" return f'KillSwitchSet: {str(self.kill_switches)}' @@ -465,6 +484,11 @@ def check_killswitch(name: str, data: UPDATABLE_DATA, log=logger) -> Tuple[bool, return active.check_killswitch(name, data, log) +def check_multiple_killswitches(data: UPDATABLE_DATA, *names: str, log=logger) -> tuple[bool, UPDATABLE_DATA]: + """Query the global KillSwitchSet#check_multiple method.""" + return active.check_multiple_killswitches(data, *names, log=log) + + def is_disabled(id: str, *, version: semantic_version.Version = _current_version) -> bool: """Query the global KillSwitchSet#is_disabled method.""" return active.is_disabled(id, version=version) diff --git a/tests/killswitch.py/test_killswitch.py b/tests/killswitch.py/test_killswitch.py index ebbae1b1..cda672ac 100644 --- a/tests/killswitch.py/test_killswitch.py +++ b/tests/killswitch.py/test_killswitch.py @@ -73,3 +73,21 @@ def test_operator_precedence( kill.apply_rules(cpy) assert cpy == result + + +@pytest.mark.parametrize( + ('names', 'input', 'result', 'expected_return'), + [ + (['no-actions', 'delete-action'], {'a': 1}, {'a': 1}, True), + # this is true because delete-action keyerrors, thus causing failsafe + (['delete-action'], {'a': 1}, {'a': 1}, True), + (['delete-action'], {'a': 1, 'b': {'c': 2}}, {'b': {}}, False), + ] +) +def test_check_multiple( + names: list[str], input: killswitch.UPDATABLE_DATA, result: killswitch.UPDATABLE_DATA, expected_return: bool +) -> None: + """Check that order is correct when checking multiple killswitches.""" + should_return, data = TEST_SET.check_multiple_killswitches(input, *names, version='1.0.0') + assert should_return == expected_return + assert data == result