Skip to content

Commit

Permalink
model.submodel: add elements to SubmodelElementList after the `_val…
Browse files Browse the repository at this point in the history
…ue` attribute has been assigned

This fixes an `AttributeError` previously raised during initialization
of a `SubmodelElementList`, since the `check_constraints` function,
which is called for every added item, may call `Referable.__repr__()`
when the `value` attribute isn't set yet. The `AttributeError` occured
because `Referable.__repr__()` accesses the `value` attribute for direct
children of a `SubmodelElementList` (1aa0e82).
This is worked around by first assigning the `OrderedNamespaceSet` to
the `value`-attribute and then adding each item separately.
  • Loading branch information
jkhsjdhjs authored and s-heppner committed Oct 3, 2023
1 parent 598f05b commit 6b4fd27
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion basyx/aas/model/submodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,19 @@ def __init__(self,

# Items must be added after the above contraint has been checked. Otherwise, it can lead to errors, since the
# constraints in _check_constraints() assume that this constraint has been checked.
self._value: base.OrderedNamespaceSet[_SE] = base.OrderedNamespaceSet(self, [("id_short", True)], value,
self._value: base.OrderedNamespaceSet[_SE] = base.OrderedNamespaceSet(self, [("id_short", True)], (),
self._check_constraints)
# SubmodelElements need to be added after the assignment of the ordered NamespaceSet, otherwise, if a constraint
# check fails, Referable.__repr__ may be called for an already-contained item during the AASd-114 check, which
# in turn tries to access the SubmodelElementLists value / _value attribute, which wouldn't be set yet if all
# elements are passed to the OrderedNamespaceSet initializer.
try:
for i in value:
self._value.add(i)
except Exception:
# Remove all SubmodelElements if an exception occurs during initialization of the SubmodelElementList
self._value.clear()
raise

def _check_constraints(self, new: _SE, existing: Iterable[_SE]) -> None:
# We can't use isinstance(new, self.type_value_list_element) here, because each subclass of
Expand Down

0 comments on commit 6b4fd27

Please sign in to comment.