From a87819392ca42159773eda61defa01abbda0a2b9 Mon Sep 17 00:00:00 2001 From: Joe Gordon Date: Tue, 5 Feb 2013 11:00:03 -0800 Subject: 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 --- openstack/common/jsonutils.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'openstack') 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: -- cgit