model.base: Protect NamespaceSet attributes from being replaced - #619
Open
zrgt wants to merge 2 commits into
Open
model.base: Protect NamespaceSet attributes from being replaced#619zrgt wants to merge 2 commits into
zrgt wants to merge 2 commits into
Conversation
Attributes like `Submodel.submodel_element`, `Qualifiable.qualifier` or `HasExtension.extension` hold a `NamespaceSet`, while the corresponding `__init__` parameters accept any `Iterable`. Assigning an iterable to such an attribute after initialization silently replaced the `NamespaceSet` with that plain object. The old `NamespaceSet` remained registered in `namespace_element_sets`, so its objects stayed reachable via `get_referable()` and friends while being invisible in the attribute, uniqueness constraints were no longer checked and the `parent` of the new objects was never set. The resulting errors, such as `AttributeError: 'list' object has no attribute 'update_nss_from'` when iterating over an `ObjectStore`, gave no hint about the actual cause. `Namespace.__setattr__` now redirects such assignments to the content of the existing `NamespaceSet`, which is the behavior a user would expect from the type of the `__init__` parameters. This is done centrally in `Namespace` instead of via a property per attribute, so that it also applies to the `NamespaceSet` attributes of classes outside of this repository. The replacement is atomic: if one of the new objects violates a constraint, the previous content of the set is restored. Fixes #65
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Attributes like
Submodel.submodel_element,Qualifiable.qualifierorHasExtension.extensionhold aNamespaceSet, while the corresponding__init__parameters accept anyIterable. Assigning an iterable tosuch an attribute after initialization silently replaced the
NamespaceSetwith that plain object. The oldNamespaceSetremainedregistered in
namespace_element_sets, so its objects stayed reachablevia
get_referable()and friends while being invisible in theattribute, uniqueness constraints were no longer checked and the
parentof the new objects was never set. The resulting errors, such asAttributeError: 'list' object has no attribute 'update_nss_from'wheniterating over an
ObjectStore, gave no hint about the actual cause.Namespace.__setattr__now redirects such assignments to the content ofthe existing
NamespaceSet, which is the behavior a user would expectfrom the type of the
__init__parameters:As discussed in the issue, this is done centrally in
Namespaceinsteadof via a property per attribute. That way it needs no repetition for
every current and future
NamespaceSetattribute and also coversNamespaceSetattributes of classes defined outside of this repository.The existing
SubmodelElementList.valuesetter keeps working unchanged.The replacement is atomic: if one of the new objects violates a
constraint, the previous content of the set is restored, so a failed
assignment leaves the object untouched.
Fixes #65