From d153b8046f52a679898089990f390e61086ec472 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 16:13:04 +0100 Subject: [PATCH 1/9] [property] return value as tuple --- odml/property.py | 2 +- test/test_property.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/odml/property.py b/odml/property.py index b02bb1fa..717cc5bc 100644 --- a/odml/property.py +++ b/odml/property.py @@ -150,7 +150,7 @@ def _validate_parent(new_parent): @property def value(self): - return self._value + return tuple(self._value) def value_str(self, index=0): """ diff --git a/test/test_property.py b/test/test_property.py index debe542c..28cd32f7 100644 --- a/test/test_property.py +++ b/test/test_property.py @@ -13,6 +13,7 @@ def setUp(self): def test_value(self): p = Property("property", 100) self.assertEqual(p.value[0], 100) + self.assertEqual(type(p.value), tuple) def test_bool_conversion(self): From 536e583f51de7e5286ca4f4f96b400d969e14c11 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 16:58:25 +0100 Subject: [PATCH 2/9] [property] extract method that converts input values to lists --- odml/property.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/odml/property.py b/odml/property.py index 717cc5bc..7ab86015 100644 --- a/odml/property.py +++ b/odml/property.py @@ -172,18 +172,32 @@ def _validate_values(self, values): return False return True - @value.setter - def value(self, new_value): - # Make sure boolean value 'False' gets through as well... - if new_value is None or new_value == "": - return + def _convert_value_input(self, new_value): + """ + This method ensures, that the passed new value is a list. + If new_value is a string, it will convert it to a list of + strings if the new_value contains embracing brackets. + + returns list of new_value + """ if isinstance(new_value, str): if new_value[0] == "[" and new_value[-1] == "]": new_value = new_value[1:-1].split(",") if not isinstance(new_value, list): new_value = [new_value] + return new_value + + @value.setter + def value(self, new_value): + # Make sure boolean value 'False' gets through as well... + if new_value is None or new_value == "": + return + + new_value = self._convert_value_input(new_value) + if self._dtype is None: self._dtype = dtypes.infer_dtype(new_value[0]) + if not self._validate_values(new_value): raise ValueError("odml.Property.value: passed values are not of " "consistent type!") From 97e64d17c62a678ecb25e7ed551548a69eba4aa4 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 16:59:18 +0100 Subject: [PATCH 3/9] [property] add append method and tests --- odml/property.py | 11 +++++++++++ test/test_property.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/odml/property.py b/odml/property.py index 7ab86015..30669d6d 100644 --- a/odml/property.py +++ b/odml/property.py @@ -322,3 +322,14 @@ def __len__(self): def __getitem__(self, key): return self._value[key] + + def append(self, obj): + if self._value == []: + self.value = obj + else: + new_value = self._convert_value_input(obj) + if not self._validate_values(new_value): + raise ValueError("odml.Property.append: passed value(s) cannot be converted to " + "data type \'%s\'!" % self._dtype) + self._value.extend([dtypes.get(v, self.dtype) for v in new_value]) + diff --git a/test/test_property.py b/test/test_property.py index 28cd32f7..884a4ec0 100644 --- a/test/test_property.py +++ b/test/test_property.py @@ -15,6 +15,14 @@ def test_value(self): self.assertEqual(p.value[0], 100) self.assertEqual(type(p.value), tuple) + p.append(10) + self.assertEqual(len(p.value), 2) + p.append([20, 30, '40']) + self.assertEqual(len(p.value), 5) + with self.assertRaises(ValueError): + p.append('invalid') + p.append(('5', 6, 7)) + def test_bool_conversion(self): # Success tests From 128f9a3173cb18a0b574a63079356ed469abd0ab Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 17:14:57 +0100 Subject: [PATCH 4/9] [test] adapatations to tuples1 --- odml/tools/dumper.py | 2 +- test/test_property.py | 10 +++++----- test/test_rdf_writer.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/odml/tools/dumper.py b/odml/tools/dumper.py index aa01b7af..dfb34a7c 100644 --- a/odml/tools/dumper.py +++ b/odml/tools/dumper.py @@ -10,7 +10,7 @@ def get_props(obj, props): if hasattr(obj, p): x = getattr(obj, p) if x is not None: - if isinstance(x, list): + if isinstance(x, list) or isinstance(x, tuple): out.append("%s=%s" % (p, to_csv(x))) else: out.append("%s=%s" % (p, repr(x))) diff --git a/test/test_property.py b/test/test_property.py index 884a4ec0..244cb2e4 100644 --- a/test/test_property.py +++ b/test/test_property.py @@ -30,13 +30,13 @@ def test_bool_conversion(self): assert(p.dtype == 'int') p.dtype = DType.boolean assert(p.dtype == 'boolean') - assert(p.value == [True, False, True, False, True]) + assert(p.value == (True, False, True, False, True)) q = Property(name='sent', value=['False', True, 'TRUE', '0', 't', 'F', '1']) assert(q.dtype == 'string') q.dtype = DType.boolean assert(q.dtype == 'boolean') - assert(q.value == [False, True, True, False, True, False, True]) + assert(q.value == (False, True, True, False, True, False, True)) # Failure tests curr_val = [3, 0, 1, 0, 8] @@ -46,7 +46,7 @@ def test_bool_conversion(self): with self.assertRaises(ValueError): p.dtype = DType.boolean assert(p.dtype == curr_type) - assert(p.value == curr_val) + assert(p.value == tuple(curr_val)) curr_type = 'string' q = Property(name='sent', value=['False', True, 'TRUE', '0', 't', '12', 'Ft']) @@ -62,7 +62,7 @@ def test_str_to_int_convert(self): assert(p.dtype == 'string') p.dtype = DType.int assert(p.dtype == 'int') - assert(p.value == [3, 0, 1, 0, 8]) + assert(p.value == (3, 0, 1, 0, 8)) # Failure Test p = Property(name='dogs_onboard', value=['7', '20', '1 Dog', 'Seven']) @@ -72,7 +72,7 @@ def test_str_to_int_convert(self): p.dtype = DType.int assert(p.dtype == 'string') - assert(p.value == ['7', '20', '1 Dog', 'Seven']) + assert(p.value == ('7', '20', '1 Dog', 'Seven')) def test_name(self): pass diff --git a/test/test_rdf_writer.py b/test/test_rdf_writer.py index dca03c3b..74fe195f 100644 --- a/test/test_rdf_writer.py +++ b/test/test_rdf_writer.py @@ -100,7 +100,7 @@ def test_adding_values(self): w.convert_to_rdf() self.assertEqual(len(list(w.g.subjects(predicate=RDF.li, object=Literal("val")))), 1) - doc.sections[0].properties[0].value.append("val2") + doc.sections[0].properties[0].append("val2") w = RDFWriter([doc]) w.convert_to_rdf() self.assertEqual(len(list(w.g.subject_objects(predicate=RDF.li))), 2) From 63846a2fcebe91c29cff0a5b8d111d065cf3e63e Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 17:45:21 +0100 Subject: [PATCH 5/9] [property] fix merging --- odml/property.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odml/property.py b/odml/property.py index 30669d6d..30324aba 100644 --- a/odml/property.py +++ b/odml/property.py @@ -281,7 +281,7 @@ def clone(self): """ obj = super(BaseProperty, self).clone() obj._section = None - obj.value = self.value + obj.value = self._value return obj def merge(self, property): From 74fccbaa14bd2249aa0380fdfbb9ba495464d7d9 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 17:46:44 +0100 Subject: [PATCH 6/9] [dictWriter] convert values to list for dict conversion --- odml/tools/dict_parser.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/odml/tools/dict_parser.py b/odml/tools/dict_parser.py index 47ea641c..d772a27d 100644 --- a/odml/tools/dict_parser.py +++ b/odml/tools/dict_parser.py @@ -80,8 +80,9 @@ def get_properties(props_list): if hasattr(prop, attr): tag = getattr(prop, attr) - - if (tag == []) or tag: # Even if 'value' is empty, allow '[]' + if isinstance(tag, tuple): + prop_dict[attr] = list(tag) + elif (tag == []) or tag: # Even if 'value' is empty, allow '[]' prop_dict[attr] = tag props_seq.append(prop_dict) From c2ba83fb18427c24a00fc52ae4616ba77ec44188 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 17:47:15 +0100 Subject: [PATCH 7/9] [dictReader] use the property value setter to properly set value --- odml/tools/dict_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odml/tools/dict_parser.py b/odml/tools/dict_parser.py index d772a27d..0d2cdf01 100644 --- a/odml/tools/dict_parser.py +++ b/odml/tools/dict_parser.py @@ -188,7 +188,7 @@ def parse_properties(self, props_list): prop_attrs[attr] = _property[attr] prop = odmlfmt.Property.create(**prop_attrs) - prop._value = values + prop.value = values odml_props.append(prop) return odml_props From 2371d49e8483dd56d8362b733b4aeaf78e42671a Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 17:59:44 +0100 Subject: [PATCH 8/9] [property] allow appending a property, i.e. appending the values --- odml/property.py | 7 +++++-- test/test_property.py | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/odml/property.py b/odml/property.py index 30324aba..79c9e373 100644 --- a/odml/property.py +++ b/odml/property.py @@ -286,9 +286,9 @@ def clone(self): def merge(self, property): """ - Stub that doesn't do anything for this class + Merges the values in 'property' into self, if possible. """ - pass + self.append(list(property.value)) def unmerge(self, property): """ @@ -324,6 +324,9 @@ def __getitem__(self, key): return self._value[key] def append(self, obj): + if isinstance(obj, BaseProperty): + self.merge(obj) + return if self._value == []: self.value = obj else: diff --git a/test/test_property.py b/test/test_property.py index 244cb2e4..bbb07602 100644 --- a/test/test_property.py +++ b/test/test_property.py @@ -23,6 +23,10 @@ def test_value(self): p.append('invalid') p.append(('5', 6, 7)) + p2 = Property("property 2", 3) + p.append(p2) + self.assertEqual(len(p.value), 6) + def test_bool_conversion(self): # Success tests From 189099c391b70be5a868ebbcf2786f8c290be63c Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Tue, 6 Mar 2018 22:32:32 +0100 Subject: [PATCH 9/9] [travis] manually install python3 via brew on macOS --- .travis.yml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 64226cd3..5e16de67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,23 +30,34 @@ before_install: install: - export PYVER=${TRAVIS_PYTHON_VERSION:0:1} + - if [ $PYVER = 3 ]; then + export PYCMD=python3; + export PIPCMD=pip3; + else + export PYCMD=python; + export PIPCMD=pip; + fi; + - if [ $COVERALLS = 1 ]; then - pip install --upgrade coveralls; + $PIPCMD install --upgrade coveralls; fi; + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - which python; + which $PYCMD; source venv/bin/activate; - which python; - fi - - pip install lxml enum34 pyyaml rdflib + brew upgrade python; + which $PYCMD; + fi; + + - $PIPCMD install lxml enum34 pyyaml rdflib script: - - which python - - python setup.py build + - which $PYCMD + - $PYCMD setup.py build - if [ $COVERALLS = 1 ]; then coverage${PYVER} run --source=odml setup.py test && coverage${PYVER} report -m; else - python setup.py test; + $PYCMD setup.py test; fi; after_success: