Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Lehrstuhl für Informations- und Automatisierungssysteme
PyI40AAS
Commits
6445aaf7
Commit
6445aaf7
authored
May 05, 2020
by
Michael Thies
Browse files
Merge branch 'feature/updatable_classes' into 'master'
Feature/updatable classes See merge request acplt/pyaas!29
parents
eb3542ba
9eadf4c2
Pipeline
#276957
passed with stage
in 3 minutes and 1 second
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
aas/model/base.py
View file @
6445aaf7
...
...
@@ -463,6 +463,41 @@ class Referable(metaclass=abc.ABCMeta):
raise
ValueError
(
"The id_short must start with a letter"
)
self
.
_id_short
=
id_short
def
update
(
self
,
timeout
:
float
=
0
)
->
None
:
"""
Update the local Referable object from the underlying backend.
If the object does not belong to a backend, i.e. it is a simple in-memory object, this function does nothing.
:param timeout: Only update the object, if it has not been updated within the last `timeout` seconds.
"""
pass
def
update_from
(
self
,
other
:
"Referable"
):
"""
Internal function to updates the object's attributes from another object of a similar type.
This function should not be used directly. It is typically used by backend implementations (database adapters,
protocol clients, etc.) to update the object's data, after `update()` has been called.
:param other: The object to update from
"""
for
name
,
var
in
vars
(
other
).
items
():
if
name
==
"parent"
:
# do not update the parent
continue
if
isinstance
(
var
,
NamespaceSet
):
# update the elements of the NameSpaceSet
vars
(
self
)[
name
].
update_nss_from
(
var
)
vars
(
self
)[
name
]
=
var
# that variable is not a NameSpaceSet, so it isn't Referable
def
commit
(
self
)
->
None
:
"""
Transfer local changes on this object to the underlying backend.
If the object does not belong to a backend, i.e. it is a simple in-memory object, this function does nothing.
"""
pass
id_short
=
property
(
_get_id_short
,
_set_id_short
)
...
...
@@ -965,6 +1000,35 @@ class NamespaceSet(MutableSet[_RT], Generic[_RT]):
"""
return
self
.
_backend
.
get
(
key
,
default
)
def
update_nss_from
(
self
,
other
:
"NamespaceSet"
):
"""
Update a NamespaceSet from a given NamespaceSet.
WARNING: By updating, the "other" NamespaceSet gets destroyed.
:param other: The NamespaceSet to update from
"""
referables_to_add
:
List
[
Referable
]
=
[]
# objects from the other nss to add to self
referables_to_remove
:
List
[
Referable
]
=
[]
# objects to remove from self
for
other_referable
in
other
:
try
:
referable
=
self
.
_backend
[
other_referable
.
id_short
]
if
type
(
referable
)
is
type
(
other_referable
):
# referable is the same as other referable
referable
.
update_from
(
other_referable
)
except
KeyError
:
# other referable is not in NamespaceSet
referables_to_add
.
append
(
other_referable
)
for
id_short
,
referable
in
self
.
_backend
.
items
():
if
not
other
.
get
(
id_short
):
# referable does not exist in the other NamespaceSet
referables_to_remove
.
append
(
referable
)
for
referable_to_add
in
referables_to_add
:
other
.
remove
(
referable_to_add
)
self
.
add
(
referable_to_add
)
# type: ignore
for
referable_to_remove
in
referables_to_remove
:
self
.
remove
(
referable_to_remove
)
# type: ignore
class
OrderedNamespaceSet
(
NamespaceSet
[
_RT
],
MutableSequence
[
_RT
],
Generic
[
_RT
]):
"""
...
...
test/model/test_base.py
View file @
6445aaf7
...
...
@@ -191,6 +191,26 @@ class ModelNamespaceTest(unittest.TestCase):
namespace2
.
set1
.
get_referable
(
'Prop1'
)
self
.
assertEqual
(
"'Prop1'"
,
str
(
cm
.
exception
))
def
test_update
(
self
):
# Prop1 is getting its value updated by namespace2.set1
# Prop2 is getting deleted since it does not exist in namespace2.set1
# Prop3 is getting added, since it does not exist in namespace1.set1 yet
namespace1
=
ExampleNamespace
()
namespace1
.
set1
.
add
(
model
.
Property
(
"Prop1"
,
model
.
datatypes
.
Int
,
1
))
namespace1
.
set1
.
add
(
model
.
Property
(
"Prop2"
,
model
.
datatypes
.
Int
,
0
))
namespace2
=
ExampleNamespace
()
namespace2
.
set1
.
add
(
model
.
Property
(
"Prop1"
,
model
.
datatypes
.
Int
,
0
))
namespace2
.
set1
.
add
(
model
.
Property
(
"Prop3"
,
model
.
datatypes
.
Int
,
2
))
namespace1
.
set1
.
update_nss_from
(
namespace2
.
set1
)
self
.
assertEqual
(
namespace1
.
set1
.
get_referable
(
"Prop1"
).
value
,
0
)
# Check that Prop1 got updated correctly
self
.
assertEqual
(
namespace1
.
set1
.
get_referable
(
"Prop3"
).
value
,
2
)
# Check that Prop3 got added
with
self
.
assertRaises
(
KeyError
)
as
cm
:
# Check that Prop2 got removed
namespace1
.
set1
.
get_referable
(
"Prop2"
)
self
.
assertEqual
(
"'Prop2'"
,
str
(
cm
.
exception
))
# Check that the parent of Prop3 is adapted correctly:
self
.
assertEqual
(
namespace1
.
get_referable
(
"Prop1"
).
parent
,
namespace1
)
self
.
assertEqual
(
namespace1
.
get_referable
(
"Prop3"
).
parent
,
namespace1
)
class
ExampleOrderedNamespace
(
model
.
Namespace
):
def
__init__
(
self
,
values
=
()):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment