Cache JSON encoders and sort keys
authorMichael Hanselmann <hansmi@google.com>
Thu, 5 Nov 2009 12:31:21 +0000 (13:31 +0100)
committerMichael Hanselmann <hansmi@google.com>
Thu, 5 Nov 2009 15:36:36 +0000 (16:36 +0100)
The sort_keys argument is supported since simplejson 1.3.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>

lib/serializer.py
test/ganeti.serializer_unittest.py

index 2b78efd..43dfaa7 100644 (file)
@@ -42,7 +42,7 @@ _JSON_INDENT = 2
 _RE_EOLSP = re.compile('[ \t]+$', re.MULTILINE)
 
 
-def _GetJsonDumpers():
+def _GetJsonDumpers(_encoder_class=simplejson.JSONEncoder):
   """Returns two JSON functions to serialize data.
 
   @rtype: (callable, callable)
@@ -50,22 +50,16 @@ def _GetJsonDumpers():
            generate a more readable, indented form of JSON (if supported)
 
   """
-  plain_dump = simplejson.dumps
+  plain_encoder = _encoder_class(sort_keys=True)
 
   # Check whether the simplejson module supports indentation
   try:
-    simplejson.dumps(1, indent=_JSON_INDENT)
+    indent_encoder = _encoder_class(indent=_JSON_INDENT, sort_keys=True)
   except TypeError:
     # Indentation not supported
-    indent_dump = plain_dump
-  else:
-    # Indentation supported
-    indent_dump = lambda data: simplejson.dumps(data, indent=_JSON_INDENT)
-
-  assert callable(plain_dump)
-  assert callable(indent_dump)
+    indent_encoder = plain_encoder
 
-  return (plain_dump, indent_dump)
+  return (plain_encoder.encode, indent_encoder.encode)
 
 
 (_DumpJson, _DumpJsonIndent) = _GetJsonDumpers()
index cb275d5..62d3b46 100755 (executable)
@@ -52,15 +52,24 @@ class TestSerializer(testutils.GanetiTestCase):
     ]
 
   def _TestSerializer(self, dump_fn, load_fn):
-    for data in self._TESTDATA:
-      self.failUnless(dump_fn(data).endswith("\n"))
-      self.assertEqualValues(load_fn(dump_fn(data)), data)
+    for indent in [True, False]:
+      for data in self._TESTDATA:
+        self.failUnless(dump_fn(data, indent=indent).endswith("\n"))
+        self.assertEqualValues(load_fn(dump_fn(data, indent=indent)), data)
 
   def testGeneric(self):
-    return self._TestSerializer(serializer.Dump, serializer.Load)
+    self._TestSerializer(serializer.Dump, serializer.Load)
 
   def testJson(self):
-    return self._TestSerializer(serializer.DumpJson, serializer.LoadJson)
+    self._TestSerializer(serializer.DumpJson, serializer.LoadJson)
+
+  def testJsonIndent(self):
+    data = {
+      "k1": 1,
+      "k2": 3,
+      "k3": 4,
+      }
+    self.assert_(len(serializer.DumpJson(data, indent=True).splitlines()) > 3)
 
   def testSignedMessage(self):
     LoadSigned = serializer.LoadSigned