changeset 2160:3754ee8ab3ad beta

improvements for extended json serializer
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 23 Mar 2012 21:36:36 +0200
parents 19b4e2832629
children e8c016815ab9
files rhodecode/lib/compat.py
diffstat 1 files changed, 33 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/compat.py	Fri Mar 23 15:52:36 2012 +0200
+++ b/rhodecode/lib/compat.py	Fri Mar 23 21:36:36 2012 +0200
@@ -27,6 +27,7 @@
 import os
 import datetime
 import functools
+import decimal
 from rhodecode import __platform__, PLATFORM_WIN
 
 #==============================================================================
@@ -34,20 +35,47 @@
 #==============================================================================
 
 
+def _is_aware(value):
+    """
+    Determines if a given datetime.time is aware.
+
+    The logic is described in Python's docs:
+    http://docs.python.org/library/datetime.html#datetime.tzinfo
+    """
+    return (value.tzinfo is not None
+            and value.tzinfo.utcoffset(value) is not None)
+
+
 def _obj_dump(obj):
     """
-    Custom function for dumping objects to JSON
+    Custom function for dumping objects to JSON, if obj has __json__ attribute
+    or method defined it will be used for serialization
 
     :param obj:
     """
-    DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
-    DATE_FORMAT = "%Y-%m-%d"
+
     if isinstance(obj, complex):
         return [obj.real, obj.imag]
+    # See "Date Time String Format" in the ECMA-262 specification.
+    # some code borrowed from django 1.4
     elif isinstance(obj, datetime.datetime):
-        return obj.strftime(DATETIME_FORMAT)
+        r = obj.isoformat()
+        if obj.microsecond:
+            r = r[:23] + r[26:]
+        if r.endswith('+00:00'):
+            r = r[:-6] + 'Z'
+        return r
     elif isinstance(obj, datetime.date):
-        return obj.strftime(DATE_FORMAT)
+        return obj.isoformat()
+    elif isinstance(obj, decimal.Decimal):
+        return str(obj)
+    elif isinstance(obj, datetime.time):
+        if _is_aware(obj):
+            raise ValueError("JSON can't represent timezone-aware times.")
+        r = obj.isoformat()
+        if obj.microsecond:
+            r = r[:12]
+        return r
     elif isinstance(obj, set):
         return list(obj)
     elif isinstance(obj, OrderedDict):