Skip to content

Commit 5c580f6

Browse files
helmut-jacoboroulet
authored andcommitted
Make sure all inverse references are removed on node deletion
Iterating over the references list and deleting inside the same list resulted in dangling inverse references if nodes where deleted. Fix this by iterating over a copy of the references list.
1 parent fd22bbc commit 5c580f6

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

opcua/server/address_space.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def _delete_node(self, item, user):
330330

331331
if item.DeleteTargetReferences:
332332
for elem in self._aspace.keys():
333-
for rdesc in self._aspace[elem].references:
333+
for rdesc in self._aspace[elem].references[:]:
334334
if rdesc.NodeId == item.NodeId:
335335
self._aspace[elem].references.remove(rdesc)
336336

tests/tests_common.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,27 @@ def test_delete_nodes(self):
118118
childs = fold.get_children()
119119
self.assertNotIn(var, childs)
120120

121+
122+
def test_delete_nodes_with_inverse_references(self):
123+
obj = self.opc.get_objects_node()
124+
fold = obj.add_folder(2, "FolderToDelete")
125+
var = fold.add_variable(2, "VarToDelete", 9.1)
126+
var2 = fold.add_variable(2, "VarWithReference", 9.2)
127+
childs = fold.get_children()
128+
self.assertIn(var, childs)
129+
self.assertIn(var2, childs)
130+
# add two references to var, this includes adding the inverse references to var2
131+
var.add_reference(var2.nodeid, reftype=ua.ObjectIds.HasDescription, forward=True, bidirectional=True)
132+
var.add_reference(var2.nodeid, reftype=ua.ObjectIds.HasEffect, forward=True, bidirectional=True)
133+
self.opc.delete_nodes([var])
134+
childs = fold.get_children()
135+
assert var not in childs
136+
has_desc_refs = var2.get_referenced_nodes(refs=ua.ObjectIds.HasDescription, direction=ua.BrowseDirection.Inverse)
137+
assert len(has_desc_refs) == 0
138+
has_effect_refs = var2.get_referenced_nodes(refs=ua.ObjectIds.HasEffect, direction=ua.BrowseDirection.Inverse)
139+
assert len(has_effect_refs) == 0
140+
141+
121142
def test_delete_nodes_recursive(self):
122143
obj = self.opc.get_objects_node()
123144
fold = obj.add_folder(2, "FolderToDeleteR")

0 commit comments

Comments
 (0)