summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Gordon <jogo@cloudscaling.com>2013-02-05 11:00:03 -0800
committerJoe Gordon <jogo@cloudscaling.com>2013-02-05 11:00:03 -0800
commitb09aa29c8882b8284aebd03617ae758397bce6f0 (patch)
tree77b41c85534aedb264279c58c2b993ce07ddcab8
parentbeb948b1d84aae66fb6e40de9b50ef25810684d3 (diff)
downloadoslo-serialization-b09aa29c8882b8284aebd03617ae758397bce6f0.tar.gz
Allow to_primitive to ignore datetimes
In preparation for having nova.db.api not return any sqlalchemy objects. nova.db.api will return only primitives, except for datetime.datetime objects. Uses functools.partial to make code DRYING Partially implements bp db-api-cleanup Change-Id: I9980d8c4e20b05bbe734cf90ac209e4e7e89befb
-rw-r--r--openstack/common/jsonutils.py34
-rw-r--r--tests/unit/test_jsonutils.py4
2 files changed, 17 insertions, 21 deletions
diff --git a/openstack/common/jsonutils.py b/openstack/common/jsonutils.py
index efc8324..b7f6bcd 100644
--- a/openstack/common/jsonutils.py
+++ b/openstack/common/jsonutils.py
@@ -34,6 +34,7 @@ This module provides a few things:
import datetime
+import functools
import inspect
import itertools
import json
@@ -42,7 +43,8 @@ import xmlrpclib
from openstack.common import timeutils
-def to_primitive(value, convert_instances=False, level=0):
+def to_primitive(value, convert_instances=False, convert_datetime=True,
+ level=0):
"""Convert a complex object into primitives.
Handy for JSON serialization. We can optionally handle instances,
@@ -84,6 +86,10 @@ def to_primitive(value, convert_instances=False, level=0):
# The try block may not be necessary after the class check above,
# but just in case ...
try:
+ recursive = functools.partial(to_primitive,
+ convert_instances=convert_instances,
+ convert_datetime=convert_datetime,
+ level=level)
# It's not clear why xmlrpclib created their own DateTime type, but
# for our purposes, make it a datetime type which is explicitly
# handled
@@ -91,33 +97,19 @@ def to_primitive(value, convert_instances=False, level=0):
value = datetime.datetime(*tuple(value.timetuple())[:6])
if isinstance(value, (list, tuple)):
- o = []
- for v in value:
- o.append(to_primitive(v, convert_instances=convert_instances,
- level=level))
- return o
+ return [recursive(v) for v in value]
elif isinstance(value, dict):
- o = {}
- for k, v in value.iteritems():
- o[k] = to_primitive(v, convert_instances=convert_instances,
- level=level)
- return o
- elif isinstance(value, datetime.datetime):
+ return dict((k, recursive(v)) for k, v in value.iteritems())
+ elif convert_datetime and isinstance(value, datetime.datetime):
return timeutils.strtime(value)
elif hasattr(value, 'iteritems'):
- return to_primitive(dict(value.iteritems()),
- convert_instances=convert_instances,
- level=level + 1)
+ return recursive(dict(value.iteritems()), level=level + 1)
elif hasattr(value, '__iter__'):
- return to_primitive(list(value),
- convert_instances=convert_instances,
- level=level)
+ return recursive(list(value))
elif convert_instances and hasattr(value, '__dict__'):
# Likely an instance of something. Watch for cycles.
# Ignore class member vars.
- return to_primitive(value.__dict__,
- convert_instances=convert_instances,
- level=level + 1)
+ return recursive(value.__dict__, level=level + 1)
else:
return value
except TypeError:
diff --git a/tests/unit/test_jsonutils.py b/tests/unit/test_jsonutils.py
index f618a05..87ac367 100644
--- a/tests/unit/test_jsonutils.py
+++ b/tests/unit/test_jsonutils.py
@@ -58,6 +58,10 @@ class ToPrimitiveTestCase(utils.BaseTestCase):
self.assertEquals(jsonutils.to_primitive(x),
'1920-02-03T04:05:06.000007')
+ def test_datetime_preserve(self):
+ x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
+ self.assertEquals(jsonutils.to_primitive(x, convert_datetime=False), x)
+
def test_DateTime(self):
x = xmlrpclib.DateTime()
x.decode("19710203T04:05:06")