summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Gordon <jogo@cloudscaling.com>2013-02-05 11:00:03 -0800
committerJoe Gordon <jogo@cloudscaling.com>2013-02-07 17:00:05 -0800
commita87819392ca42159773eda61defa01abbda0a2b9 (patch)
treedabb8d0ad9751c590d67e4c5cfeb911d0c6bf375
parent868a530aa65de371ffae6e0afb271ff96fe1201f (diff)
downloadoslo-a87819392ca42159773eda61defa01abbda0a2b9.tar.gz
oslo-a87819392ca42159773eda61defa01abbda0a2b9.tar.xz
oslo-a87819392ca42159773eda61defa01abbda0a2b9.zip
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")