Skip to content

Commit 04b408f

Browse files
authored
Merge pull request #296 from mpsonntag/fixConverter
Fix VersionConverter encoding issue LGTM
2 parents a75d1db + 46a4fbb commit 04b408f

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

.travis.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ matrix:
1515
- os: linux
1616
python: "3.6"
1717

18-
- os: osx
19-
language: generic
20-
env:
21-
- OSXENV=3.5.0
2218
- os: osx
2319
language: generic
2420
env:

odml/tools/version_converter.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def _parse_xml(self):
5252
if elem in doc:
5353
doc = doc.replace(elem, val)
5454

55+
# Make sure encoding is present for the xml parser
56+
doc = doc.encode('utf-8')
57+
5558
# Make pretty print available by resetting format
5659
parser = ET.XMLParser(remove_blank_text=True)
5760
tree = ET.ElementTree(ET.fromstring(doc, parser))
@@ -300,7 +303,7 @@ def _handle_properties(self, root):
300303

301304
if value.text:
302305
if main_val.text:
303-
main_val.text += ", " + value.text.strip()
306+
main_val.text += "," + value.text.strip()
304307
multiple_values = True
305308
else:
306309
main_val.text = value.text.strip()

odml/tools/xmlparser.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@
2727

2828

2929
def to_csv(val):
30-
unicode_values = list(map(unicode, val))
30+
# Make sure all individual values do not contain
31+
# leading or trailing whitespaces.
32+
unicode_values = list(map(unicode.strip, map(unicode, val)))
3133
stream = StringIO()
3234
writer = csv.writer(stream, dialect="excel")
3335
writer.writerow(unicode_values)
34-
csv_string = stream.getvalue().strip()
36+
# Strip any csv.writer added carriage return line feeds
37+
# and double quotes before saving.
38+
csv_string = stream.getvalue().strip().strip('"')
3539
if len(unicode_values) > 1:
3640
csv_string = "[" + csv_string + "]"
3741
return csv_string
@@ -40,8 +44,14 @@ def to_csv(val):
4044
def from_csv(value_string):
4145
if not value_string:
4246
return []
43-
if value_string[0] == "[":
47+
if value_string[0] == "[" and value_string[-1] == "]":
4448
value_string = value_string[1:-1]
49+
else:
50+
# This is a single string entry, any comma contained
51+
# is part of the value and must not be used to
52+
# split up the string.
53+
return [value_string]
54+
4555
if not value_string:
4656
return []
4757
stream = StringIO(value_string)

test/test_version_converter.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def test_convert_odml_file(self):
130130
self.assertEqual(val_elems[0].find("unit"), None)
131131
self.assertEqual(val_elems[0].find("type"), None)
132132
self.assertEqual(val_elems[0].find("uncertainty"), None)
133-
self.assertEqual(val_elems[0].text, "[0, 45]")
133+
self.assertEqual(val_elems[0].text, "[0,45]")
134134
self.assertEqual(prop.find("unit").text, "deg")
135135
self.assertEqual(len(prop.findall("unit")), 1)
136136
self.assertEqual(prop.find("type").text, "int")
@@ -481,6 +481,37 @@ def test_convert_odml_file_value(self):
481481
</value>
482482
</property>
483483
484+
<property>
485+
<value>Single, string, value, with, many, commata.<type>string</type></value>
486+
<name>testSingleString</name>
487+
</property>
488+
489+
<property>
490+
<value>A<type>string</type></value>
491+
<value>B<type>string</type></value>
492+
<value>C<type>string</type></value>
493+
<name>testStringList</name>
494+
</property>
495+
496+
<property>
497+
<value> Single string value with wrapping whitespace <type>string</type></value>
498+
<name>testStringWhiteSpace</name>
499+
</property>
500+
501+
<property>
502+
<value> Multiple Strings <type>string</type></value>
503+
<value> with wrapping <type>string</type></value>
504+
<value> Whitespace <type>string</type></value>
505+
<name>testStringListWhiteSpace</name>
506+
</property>
507+
508+
<property>
509+
<value> 1 <type>int</type></value>
510+
<value> 2 <type>int</type></value>
511+
<value> 3 <type>int</type></value>
512+
<name>testIntListWhiteSpace</name>
513+
</property>
514+
484515
</section>
485516
</odML>
486517
"""
@@ -490,7 +521,7 @@ def test_convert_odml_file_value(self):
490521
conv_doc = vc._convert(vc._parse_xml())
491522
root = conv_doc.getroot()
492523
sec = root.find("section")
493-
self.assertEqual(len(sec), 9)
524+
self.assertEqual(len(sec), 14)
494525

495526
# Test single value export
496527
prop = sec.findall("property")[0]
@@ -500,7 +531,7 @@ def test_convert_odml_file_value(self):
500531
# Test multiple value export
501532
prop = sec.findall("property")[1]
502533
self.assertEqual(len(prop), 2)
503-
self.assertEqual(prop.find("value").text, "[1, 2, 3]")
534+
self.assertEqual(prop.find("value").text, "[1,2,3]")
504535

505536
# Test empty value export
506537
prop = sec.findall("property")[2]
@@ -521,7 +552,7 @@ def test_convert_odml_file_value(self):
521552
# Test valid multiple Value tag export
522553
prop = sec.findall("property")[4]
523554
self.assertEqual(len(prop), 7)
524-
self.assertEqual(prop.find("value").text, "[0.1, 0.2, 3]")
555+
self.assertEqual(prop.find("value").text, "[0.1,0.2,3]")
525556
self.assertEqual(prop.find("type").text, "float")
526557
self.assertEqual(prop.find("uncertainty").text, "0.05")
527558
self.assertEqual(prop.find("unit").text, "mV")
@@ -541,6 +572,35 @@ def test_convert_odml_file_value(self):
541572
self.assertEqual(prop.find("name").text, "Unsupported binary value dtype replace")
542573
self.assertEqual(prop.find("type").text, "text")
543574

575+
# Test single string value with commata
576+
prop = sec.findall("property")[8]
577+
self.assertEqual(prop.find("name").text, "testSingleString")
578+
self.assertEqual(prop.find("value").text,
579+
"Single, string, value, with, many, commata.")
580+
581+
# Test string list import
582+
prop = sec.findall("property")[9]
583+
self.assertEqual(prop.find("name").text, "testStringList")
584+
self.assertEqual(prop.find("value").text, "[A,B,C]")
585+
586+
# Test single string values wrapping whitespace removal
587+
prop = sec.findall("property")[10]
588+
self.assertEqual(prop.find("name").text, "testStringWhiteSpace")
589+
self.assertEqual(prop.find("value").text,
590+
"Single string value with wrapping whitespace")
591+
592+
# Test multiple string values with wrapping whitespace removal
593+
prop = sec.findall("property")[11]
594+
self.assertEqual(prop.find("name").text, "testStringListWhiteSpace")
595+
self.assertEqual(prop.find("value").text,
596+
"[Multiple Strings,with wrapping,Whitespace]")
597+
598+
# Test multiple int values with wrapping whitespaces
599+
prop = sec.findall("property")[12]
600+
self.assertEqual(prop.find("name").text, "testIntListWhiteSpace")
601+
self.assertEqual(prop.find("type").text, "int")
602+
self.assertEqual(prop.find("value").text, "[1,2,3]")
603+
544604
def test_parse_dict_document(self):
545605
# Test appending tags; not appending empty sections
546606
doc_dict = {'Document': {'author': 'HPL', 'sections': []}}

0 commit comments

Comments
 (0)