diff --git a/basyx/aas/model/base.py b/basyx/aas/model/base.py index a9334727b..b6a3a15e7 100644 --- a/basyx/aas/model/base.py +++ b/basyx/aas/model/base.py @@ -1287,6 +1287,13 @@ def insert(self, index: int, value: _T) -> None: self._item_add_hook(value, self._list) self._list.insert(index, value) + def extend(self, values: Iterable[_T]) -> None: + v_list = list(values) + if self._item_add_hook is not None: + for idx, v in enumerate(v_list): + self._item_add_hook(v, self._list + v_list[:idx]) + self._list = self._list + v_list + @overload def __getitem__(self, index: int) -> _T: ... diff --git a/test/model/test_base.py b/test/model/test_base.py index 47128a804..cde414573 100644 --- a/test/model/test_base.py +++ b/test/model/test_base.py @@ -1115,6 +1115,31 @@ def del_hook(itm: int, list_: List[int]) -> None: check_list.pop() self.assertEqual(c_list, check_list) + def test_atomicity(self) -> None: + def hook(itm: int, _list: List[int]) -> None: + if itm > 2: + raise ValueError + + c_list: model.ConstrainedList[int] = model.ConstrainedList([], item_add_hook=hook) + with self.assertRaises(ValueError): + c_list = model.ConstrainedList([1, 2, 3], item_add_hook=hook) + self.assertEqual(c_list, []) + with self.assertRaises(ValueError): + c_list.extend([1, 2, 3]) + self.assertEqual(c_list, []) + c_list.extend([1, 2]) + self.assertEqual(c_list, [1, 2]) + + c_list = model.ConstrainedList([1, 2, 3], item_del_hook=hook) + with self.assertRaises(ValueError): + del c_list[0:3] + self.assertEqual(c_list, [1, 2, 3]) + with self.assertRaises(ValueError): + c_list.clear() + self.assertEqual(c_list, [1, 2, 3]) + del c_list[0:2] + self.assertEqual(c_list, [3]) + class LangStringSetTest(unittest.TestCase): def test_language_tag_constraints(self) -> None: