diff --git a/sdk/basyx/aas/model/base.py b/sdk/basyx/aas/model/base.py index c9c8c8fe..1d3a18e5 100644 --- a/sdk/basyx/aas/model/base.py +++ b/sdk/basyx/aas/model/base.py @@ -2070,8 +2070,10 @@ def discard(self, x: _NSO) -> None: def pop(self) -> _NSO: _, value = next(iter(self._backend.values()))[0].popitem() + for key_attr_name, (backend_dict, case_sensitive) in self._backend.items(): + key_attr_value = self._get_attribute(value, key_attr_name, case_sensitive) + backend_dict.pop(key_attr_value, None) self._execute_item_del_hook(value) - value.parent = None return value def clear(self) -> None: diff --git a/sdk/test/model/test_base.py b/sdk/test/model/test_base.py index e300cc1f..65d49ea0 100644 --- a/sdk/test/model/test_base.py +++ b/sdk/test/model/test_base.py @@ -333,6 +333,18 @@ def setUp(self): self.namespace = self._namespace_class() self.namespace3 = self._namespace_class_qualifier() + def test_namespaceset_pop_removes_from_all_backends(self) -> None: + # set1 has two backends: id_short and semantic_id + self.namespace.set1.add(self.prop1) + popped = self.namespace.set1.pop() + self.assertIs(self.prop1, popped) + self.assertEqual(0, len(self.namespace.set1)) + # After pop, adding a new item with the same semantic_id must NOT raise AASConstraintViolation — + # it would if the popped item's semantic_id entry were still in the backend + new_prop = model.Property("NewProp", model.datatypes.Int, semantic_id=self.propSemanticID) + self.namespace.set1.add(new_prop) + self.assertEqual(1, len(self.namespace.set1)) + def test_NamespaceSet(self) -> None: self.namespace.set1.add(self.prop1) self.assertEqual(1, len(self.namespace.set1))