Repository: EmilStenstrom/conllu

Issue:
BUG: Error when serializing metadata that is not a string
```
     37         for key, value in tokenlist.metadata.items():
     38             if value:
---> 39                 line = "# " + key + " = " + value
     40             else:
     41                 line = "# " + key

TypeError: can only concatenate str (not "int") to str
```
I have written a metadata_parser that converts values to `int` which is used in my downstream tasks. However, the serializer then breaks. A simple fix can be achieved by using f-strings (which we should be using anyway, now that there is a python 3.6 requirement)

Discussion:
EmilStenstrom: Hi @hrishikeshrt! Looks good in general.

Would you mind adding some tests?
hrishikeshrt: @EmilStenstrom I've added a test case. Please let me know if you think that is sufficient.

Patch:
diff --git a/conllu/serializer.py b/conllu/serializer.py
index 39e9854..aa8fd4c 100644
--- a/conllu/serializer.py
+++ b/conllu/serializer.py
@@ -36,9 +36,9 @@ def serialize(tokenlist: 'TokenList') -> str:
     if tokenlist.metadata:
         for key, value in tokenlist.metadata.items():
             if value:
-                line = "# " + key + " = " + value
+                line = f"# {key} = {value}"
             else:
-                line = "# " + key
+                line = f"# {key}"
             lines.append(line)
 
     for token_data in tokenlist:


Test patch:
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 27f524f..de0b9ef 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -768,6 +768,28 @@ class TestSerialize(unittest.TestCase):
         tokenlist = parse_token_and_metadata(data)
         self.assertEqual(serialize(tokenlist), data)
 
+    def test_non_str_metadata(self):
+        data = dedent("""\
+            # line_id = 128
+            # weight = 3.14
+            1\tdog
+
+        """)
+        tokenlist = parse_token_and_metadata(
+            data,
+            metadata_parsers={
+                "line_id": lambda k, v: (k, int(v)),
+                "weight": lambda k, v: (k, float(v))
+            }
+        )
+        self.assertIsInstance(tokenlist.metadata['line_id'], int)
+        self.assertEqual(tokenlist.metadata['line_id'], 128)
+
+        self.assertIsInstance(tokenlist.metadata['weight'], float)
+        self.assertEqual(tokenlist.metadata['weight'], 3.14)
+
+        self.assertEqual(serialize(tokenlist), data)
+
     def test_serialize_tricky_fields(self):
         data = dedent("""\
             5\tjumps\tjump\tVERB\tVBZ\tMood=Ind|Number=Sing\t0\troot\t_\tSpaceAfter=No