changeset 119:b75de48a618c

Support boolean and None types
author Stefano Rivera <stefano@rivera.za.net>
date Mon, 02 Sep 2013 15:27:51 +0200
parents c02a99502a90
children e6e7a471146a
files nagslang/tests/test_yamlish.py nagslang/yamlish.py
diffstat 2 files changed, 37 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/tests/test_yamlish.py	Mon Sep 02 15:44:57 2013 +0200
+++ b/nagslang/tests/test_yamlish.py	Mon Sep 02 15:27:51 2013 +0200
@@ -79,6 +79,13 @@
             ],
         })
 
+    def test_quoted(self):
+        # a literal true is True, but 'true' is a string
+        self.roundtrip({'foo': 'true'})
+
+    def test_literals(self):
+        self.roundtrip({'foo': [True, False, None]})
+
 
 class TestFromPyYAML(TestRoundTrip):
     def dump_s(self, data):
--- a/nagslang/yamlish.py	Mon Sep 02 15:44:57 2013 +0200
+++ b/nagslang/yamlish.py	Mon Sep 02 15:27:51 2013 +0200
@@ -1,7 +1,10 @@
 '''
 Serializer and dumper for a simple, YAMLish format (actually a YAML subset).
 The top level object is a dict.
-lists and dicts can contain lists, dicts, and strings.
+lists and dicts can contain:
+ * lists, dicts,
+ * single line strings,
+ * True, False, and None
 '''
 
 import re
@@ -33,6 +36,8 @@
             if isinstance(data, type_):
                 f = getattr(self, '_dump_%s' % type_.__name__)
                 return f(data, indent)
+        if data in (True, False, None):
+            return self._dump_literal(data, indent)
         raise NotImplementedError()
 
     def _dump_list(self, data, indent):
@@ -58,8 +63,18 @@
         return output
 
     def _dump_basestring(self, data, indent):
+        if data in ('true', 'false', 'null'):
+            data = "'%s'" % data
         return [' ' * indent + data]
 
+    def _dump_literal(self, data, indent):
+        string = {
+            True: 'true',
+            False: 'false',
+            None: 'null',
+        }[data]
+        return [' ' * indent + string]
+
 
 class Parser(object):
     _spaces_re = re.compile(r'^(\s*)(.*)')
@@ -143,14 +158,25 @@
                     self._push(dict, self._indent + len(prefix))
                 else:
                     assert self._in_list
-                    self._container.append(line)
+                    self._container.append(self._parse_value(line))
 
             if dm:
                 key, value = dm.groups()
+                assert self._in_dict
                 if value:
-                    assert self._in_dict
-                    self._container[key] = value
+                    self._container[key] = self._parse_value(value)
                 else:
                     self._parent_key = key
 
         return self._stack[0][1]
+
+    def _parse_value(self, value):
+        if value.startswith("'") and value.endswith("'"):
+            return value[1:-1]
+        if value == 'true':
+            return True
+        if value == 'false':
+            return False
+        if value == 'null':
+            return None
+        return value