diff options
author | Joe Gordon <jogo@cloudscaling.com> | 2013-02-05 11:00:03 -0800 |
---|---|---|
committer | Joe Gordon <jogo@cloudscaling.com> | 2013-02-05 11:00:03 -0800 |
commit | b09aa29c8882b8284aebd03617ae758397bce6f0 (patch) | |
tree | 77b41c85534aedb264279c58c2b993ce07ddcab8 | |
parent | beb948b1d84aae66fb6e40de9b50ef25810684d3 (diff) | |
download | oslo-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.py | 34 | ||||
-rw-r--r-- | tests/unit/test_jsonutils.py | 4 |
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") |