diff --git a/odml/property.py b/odml/property.py index a120ab38..8801325d 100644 --- a/odml/property.py +++ b/odml/property.py @@ -328,8 +328,13 @@ def values(self, new_value): self._dtype = dtypes.infer_dtype(new_value[0]) if not self._validate_values(new_value): - raise ValueError("odml.Property.values: passed values are not of " - "consistent type!") + if self._dtype in ("date", "time", "datetime"): + raise ValueError("odml.Property.values: passed values are not of " + "consistent type \'%s\'! Format should be \'%s\'." % + (self._dtype, dtypes.default_values(self._dtype))) + else: + raise ValueError("odml.Property.values: passed values are not of " + "consistent type!") self._values = [dtypes.get(v, self.dtype) for v in new_value] @property @@ -662,3 +667,27 @@ def pprint(self, indent=2, max_length=80, current_depth=-1): else: print(("{}{} {}: {}".format(property_spaces, prefix, self.name, value_string))) + + def export_leaf(self): + """ + Export only the path from this property to the root. + Include all properties of parent sections. + """ + curr = self.parent + par = self.parent + child = self.parent + + while curr is not None: + par = curr.clone(children=False, keep_id=True) + if curr != self.parent: + par.append(child) + if hasattr(curr, 'properties'): + if curr == self.parent: + par.append(self.clone(keep_id=True)) + else: + for prop in curr.properties: + par.append(prop.clone(keep_id=True)) + child = par + curr = curr.parent + + return par diff --git a/odml/section.py b/odml/section.py index f27c724b..c195f4be 100644 --- a/odml/section.py +++ b/odml/section.py @@ -638,3 +638,24 @@ def pprint(self, indent=2, max_depth=1, max_length=80, current_depth=0): print("{} {} [{}]\n{}[...]".format(child_sec_indent, s.name, s.type, more_indent)) + + def export_leaf(self): + """ + Export only the path from this section to the root. + Include all properties for all sections, but no other subsections. + """ + curr = self + par = self + child = self + + while curr is not None: + par = curr.clone(children=False, keep_id=True) + if curr != self: + par.append(child) + if hasattr(curr, 'properties'): + for prop in curr.properties: + par.append(prop.clone(keep_id=True)) + child = par + curr = curr.parent + + return par diff --git a/test/test_property.py b/test/test_property.py index 80f6c1cc..95048f17 100644 --- a/test/test_property.py +++ b/test/test_property.py @@ -1,5 +1,7 @@ import unittest +import datetime + from odml import Property, Section, Document, DType from odml.property import BaseProperty from odml.section import BaseSection @@ -115,6 +117,19 @@ def test_value(self): self.assertEqual(p5.value, [0]) self.assertEqual(p5.values, [0]) + with self.assertRaises(ValueError): + Property(name="dateprop", dtype=DType.date, value=['20190707']) + + with self.assertRaises(ValueError): + Property(name="timeprop", dtype=DType.time, value=['11.11.11']) + + with self.assertRaises(ValueError): + Property(name="datetimeprop", dtype=DType.datetime, value=['20190707']) + + with self.assertRaises(ValueError): + Property(name="intprop", dtype=DType.int, value=[2, "Hello!", 4]) + + def test_value_append(self): # Test append w/o Property value or dtype prop = Property(name="append") @@ -733,6 +748,42 @@ def test_comparison(self): prop_b.name = 'newPropertyName' self.assertNotEqual(prop_a, prop_b) + def test_export_leaf(self): + doc = Document() + first = doc.create_section("first") + second = first.create_section("second") + first.create_section("third") + + name = "prop1" + values = [1.3] + first.create_property(name, value=values) + + name = "prop2" + values = ["words"] + second.create_property(name, value=values) + + name = "prop3" + values = ["a", "b"] + second.create_property(name, value=values) + + name = "prop4" + values = [3] + second.create_property(name, value=values) + + name = "prop5" + values = ["abc"] + first.create_property(name, value=values) + + ex1 = first.properties["prop1"].export_leaf() + self.assertEqual(len(ex1['first'].properties), 1) + self.assertEqual(len(ex1['first'].sections), 0) + + ex2 = second.properties["prop2"].export_leaf() + self.assertEqual(len(ex2.sections), 1) + self.assertEqual(len(ex2['first'].properties), 2) + self.assertEqual(len(ex2['first'].sections), 1) + self.assertEqual(len(ex2['first']['second'].properties), 1) + if __name__ == "__main__": print("TestProperty") diff --git a/test/test_section.py b/test/test_section.py index ba4e3743..ae990199 100644 --- a/test/test_section.py +++ b/test/test_section.py @@ -943,6 +943,41 @@ def test_create_property(self): prop = root.create_property(name, dtype=dtype) self.assertIsNone(prop.dtype) + def test_export_leaf(self): + doc = Document() + first = doc.create_section("first") + second = first.create_section("second") + third = first.create_section("third") + + name = "prop1" + values = [1.3] + first.create_property(name, value=values) + + name = "prop2" + values = ["words"] + first.create_property(name, value=values) + + name = "prop3" + values = ["a", "b"] + second.create_property(name, value=values) + + ex1 = first.export_leaf() + self.assertEqual(len(ex1.sections), 1) + self.assertEqual(len(ex1['first'].properties), 2) + self.assertEqual(len(ex1['first'].sections), 0) + + ex2 = second.export_leaf() + self.assertEqual(len(ex2.sections), 1) + self.assertEqual(len(ex2['first'].properties), 2) + self.assertEqual(len(ex2['first'].sections), 1) + self.assertEqual(len(ex2['first']['second'].properties), 1) + + ex3 = third.export_leaf() + self.assertEqual(len(ex3.sections), 1) + self.assertEqual(len(ex3['first'].properties), 2) + self.assertEqual(len(ex3['first'].sections), 1) + self.assertEqual(len(ex3['first']['third']), 0) + def test_link(self): pass