From 47f976649980fcde3bc4b8bc26cf2870a4461ddf Mon Sep 17 00:00:00 2001
From: Tamas Gal <tgal@km3net.de>
Date: Mon, 1 Feb 2021 22:28:10 +0100
Subject: [PATCH] Improve header handling for weird headers

---
 km3io/offline.py      | 21 +++++++++++----------
 tests/test_offline.py | 11 +++++++++++
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/km3io/offline.py b/km3io/offline.py
index f6d7bbd..6fd13b2 100644
--- a/km3io/offline.py
+++ b/km3io/offline.py
@@ -108,7 +108,10 @@ class Header:
             n_fields = len(fields)
 
             if n_values == 1 and n_fields == 0:
-                self._data[attribute] = to_num(values[0])
+                entry = to_num(values[0])
+                self._data[attribute] = entry
+                if attribute.isidentifier():
+                    setattr(self, attribute, entry)
                 continue
 
             n_max = max(n_values, n_fields)
@@ -118,16 +121,14 @@ class Header:
             if not values:
                 continue
 
-            entry = {f: to_num(v) for (f, v) in zip(fields, values)}
-            try:
-                self._data[attribute] = namedtuple(attribute, fields)(**entry)
-            except ValueError:
-                self._data[attribute] = [to_num(v) for v in values]
+            cls_name = attribute if attribute.isidentifier() else "HeaderEntry"
+            entry = namedtuple(cls_name, fields)(*[to_num(v) for v in values])
 
-        for attribute, value in self._data.items():
-            try:
-                setattr(self, attribute, value)
-            except ValueError:
+            self._data[attribute] = entry
+
+            if attribute.isidentifier():
+                setattr(self, attribute, entry)
+            else:
                 log.warning(
                     f"Invalid attribute name for header entry '{attribute}'"
                     ", access only as dictionary key."
diff --git a/tests/test_offline.py b/tests/test_offline.py
index 63f6c8e..2f59f05 100644
--- a/tests/test_offline.py
+++ b/tests/test_offline.py
@@ -102,15 +102,26 @@ class TestHeader(unittest.TestCase):
         head = {
             "a": "1 2 3",
             "b+c": "4 5 6",
+            "c": "foo",
+            "d": "7",
+            "e+f": "bar",
         }
 
         header = Header(head)
         assert 1 == header["a"][0]
         assert 2 == header["a"][1]
         assert 3 == header["a"][2]
+        assert 1 == header.a[0]
+        assert 2 == header.a[1]
+        assert 3 == header.a[2]
         assert 4 == header["b+c"][0]
         assert 5 == header["b+c"][1]
         assert 6 == header["b+c"][2]
+        assert "foo" == header.c
+        assert "foo" == header["c"]
+        assert 7 == header.d
+        assert 7 == header["d"]
+        assert "bar" == header["e+f"]
 
     def test_reading_header_from_sample_file(self):
         head = OFFLINE_NUMUCC.header
-- 
GitLab