Skip to content
Snippets Groups Projects
Commit 18521a40 authored by Alexander Schlemmer's avatar Alexander Schlemmer
Browse files

FIX: fixed a problem with recursion in high level api

parent dc131007
No related branches found
No related tags found
2 merge requests!57RELEASE 0.7.3,!52F refactor high level api
Pipeline #20409 passed with warnings
......@@ -674,7 +674,7 @@ class CaosDBPythonEntity(object):
return entity
def serialize(self, without_metadata: bool = False):
def serialize(self, without_metadata: bool = False, visited: dict = None):
"""
Serialize necessary information into a dict.
......@@ -682,19 +682,27 @@ class CaosDBPythonEntity(object):
If True don't set the metadata field in order to increase
readability. Not recommended if deserialization is needed.
"""
if visited is None:
visited = dict()
if self in visited:
return visited[self]
metadata: dict[str, Any] = dict()
properties = dict()
parents = list()
# The full information to be returned:
fulldict = dict()
visited[self] = fulldict
# Add CaosDB role:
fulldict["role"] = standard_type_for_high_level_type(self, True)
for parent in self._parents:
if isinstance(parent, CaosDBPythonEntity):
parents.append(parent.serialize())
parents.append(parent.serialize(without_metadata, visited))
elif isinstance(parent, CaosDBPythonUnresolvedParent):
parents.append({"name": parent.name, "id": parent.id,
"unresolved": True})
......@@ -722,7 +730,7 @@ class CaosDBPythonEntity(object):
if isinstance(val, CaosDBPythonUnresolvedReference):
properties[p] = {"id": val.id, "unresolved": True}
elif isinstance(val, CaosDBPythonEntity):
properties[p] = val.serialize(without_metadata)
properties[p] = val.serialize(without_metadata, visited)
elif isinstance(val, list):
serializedelements = []
for element in val:
......@@ -732,7 +740,9 @@ class CaosDBPythonEntity(object):
elm["unresolved"] = True
serializedelements.append(elm)
elif isinstance(element, CaosDBPythonEntity):
serializedelements.append(element.serialize(without_metadata))
serializedelements.append(
element.serialize(without_metadata,
visited))
else:
serializedelements.append(element)
properties[p] = serializedelements
......@@ -749,8 +759,11 @@ class CaosDBPythonEntity(object):
def __str__(self):
return yaml.dump(self.serialize(False))
def __repr__(self):
return yaml.dump(self.serialize(True))
# This seemed like a good solution, but makes it difficult to
# compare python objects directly:
#
# def __repr__(self):
# return yaml.dump(self.serialize(True))
class CaosDBPythonRecord(CaosDBPythonEntity):
......
......@@ -591,6 +591,45 @@ def test_deserialization():
obj_des = CaosDBPythonEntity.deserialize(serial)
assert obj.serialize() == obj_des.serialize()
@pytest.fixture
def get_record_container():
record_xml = """
<Entities>
<Record id="109">
<Version id="da669fce50554b2835c3826cf717d6a4532f02de" head="true">
<Predecessor id="68534369c5fd05e5bb1d37801a3dbc1532a8e094"/>
</Version>
<Parent id="103" name="Experiment" description="General type for all experiments in our lab"/>
<Property id="104" name="alpha" description="A fictitious measurement" datatype="DOUBLE" unit="km" importance="FIX" flag="inheritance:FIX">16.0</Property>
<Property id="107" name="date" datatype="DATETIME" importance="FIX" flag="inheritance:FIX">2022-03-16</Property>
<Property id="108" name="identifier" datatype="TEXT" importance="FIX" flag="inheritance:FIX">Demonstration</Property>
<Property id="111" name="sources" description="The elements of this lists are scientific activities that this scientific activity is based on." datatype="LIST&lt;ScientificActivity&gt;" importance="FIX" flag="inheritance:FIX">
<Value>109</Value>
</Property>
</Record>
</Entities>"""
c = db.Container.from_xml(record_xml)
return c
def test_recursion(get_record_container):
r = convert_to_python_object(get_record_container[0])
r.resolve_references(r, get_record_container)
assert r.id == 109
assert r.sources[0].id == 109
assert r.sources[0].sources[0].id == 109
assert "&id001" in str(r)
assert "*id001" in str(r)
d = r.serialize(True)
assert r.sources[0] == r.sources[0].sources[0]
def test_recursion():
pass
@pytest.mark.xfail
def test_recursion_advanced(get_record_container):
# TODO:
# This currently fails, because resolve is done in a second step
# and therefore a new python object is created for the reference.
r = convert_to_python_object(get_record_container[0])
r.resolve_references(r, get_record_container)
d = r.serialize(True)
assert r == r.sources[0]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment