[utils] provide a class to extend the default simplejson encoder to be able to dump standard yams attribute types 3.5
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Tue, 15 Sep 2009 16:00:03 +0200
branch3.5
changeset 3231 3ee43e2f8560
parent 3223 480b003cd31b
child 3232 eccb7380dc3b
[utils] provide a class to extend the default simplejson encoder to be able to dump standard yams attribute types
test/unittest_utils.py
utils.py
--- a/test/unittest_utils.py	Tue Sep 15 14:13:59 2009 +0200
+++ b/test/unittest_utils.py	Tue Sep 15 16:00:03 2009 +0200
@@ -8,7 +8,11 @@
 
 from logilab.common.testlib import TestCase, unittest_main
 
-from cubicweb.utils import make_uid, UStringIO, SizeConstrainedList
+import simplejson
+import decimal
+import datetime
+
+from cubicweb.utils import make_uid, UStringIO, SizeConstrainedList, CubicWebJsonEncoder
 
 
 class MakeUidTC(TestCase):
@@ -48,6 +52,24 @@
             l.extend(extension)
             yield self.assertEquals, l, expected
 
+class JSONEncoerTests(TestCase):
+
+    def encode(self, value):
+        return simplejson.dumps(value, cls=CubicWebJsonEncoder)
+
+    def test_encoding_dates(self):
+        self.assertEquals(self.encode(datetime.datetime(2009, 9, 9, 20, 30)),
+                          '"2009/09/09 20:30:00"')
+        self.assertEquals(self.encode(datetime.date(2009, 9, 9)),
+                          '"2009/09/09"')
+        self.assertEquals(self.encode(datetime.time(20, 30)),
+                          '"20:30:00"')
+
+    def test_encoding_decimal(self):
+        self.assertEquals(self.encode(decimal.Decimal('1.2')), '1.2')
+
+    def test_encoding_unknown_stuff(self):
+        self.assertEquals(self.encode(TestCase), 'null')
 
 if __name__ == '__main__':
     unittest_main()
--- a/utils.py	Tue Sep 15 14:13:59 2009 +0200
+++ b/utils.py	Tue Sep 15 16:00:03 2009 +0200
@@ -11,10 +11,14 @@
 
 import locale
 from md5 import md5
+import datetime as pydatetime
 from datetime import datetime, timedelta, date
 from time import time, mktime
 from random import randint, seed
 from calendar import monthrange
+import decimal
+
+import simplejson
 
 # initialize random seed from current time
 seed()
@@ -348,3 +352,22 @@
         return False
     __answer[0] = True
     return True
+
+
+class CubicWebJsonEncoder(simplejson.JSONEncoder):
+    """define a simplejson encoder to be able to encode yams std types"""
+    def default(self, obj):
+        if isinstance(obj, pydatetime.datetime):
+            return obj.strftime('%Y/%m/%d %H:%M:%S')
+        elif isinstance(obj, pydatetime.date):
+            return obj.strftime('%Y/%m/%d')
+        elif isinstance(obj, pydatetime.time):
+            return obj.strftime('%H:%M:%S')
+        elif isinstance(obj, decimal.Decimal):
+            return float(obj)
+        try:
+            return simplejson.JSONEncoder.default(self, obj)
+        except TypeError:
+            # we never ever want to fail because of an unknown type,
+            # just return None in those cases.
+            return None