~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/openstack/common/jsonutils.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Adam Gandelman
  • Date: 2013-02-22 09:27:29 UTC
  • mfrom: (1.1.68)
  • Revision ID: package-import@ubuntu.com-20130222092729-nn3gt8rf97uvts77
Tags: 2013.1.g3-0ubuntu1
[ Chuck Short ]
* New usptream release. 
* debian/patches/debian/patches/fix-ubuntu-tests.patch: Refreshed.
* debian/nova-baremetal.logrotate: Fix logfile path.
* debian/control, debian/nova-spiceproxy.{install, logrotate, upstart}:
  Add spice html5 proxy support.
* debian/nova-novncproxy.upstart: Start on runlevel [2345]
* debian/rules: Call testr directly since run_tests.sh -N gives weird return
  value when tests pass.
* debian/pyddist-overrides: Add websockify.
* debian/nova-common.postinst: Removed config file conversion, since
  the option is no longer available. (LP: #1110567)
* debian/control: Add python-pyasn1 as a dependency.
* debian/control: Add python-oslo-config as a dependency.
* debian/control: Suggest sysfsutils, sg3-utils, multipath-tools for fibre
  channel support.

[ Adam Gandelman ]
* debian/control: Fix typo (websocikfy -> websockify).

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
 
36
36
import datetime
 
37
import functools
37
38
import inspect
38
39
import itertools
39
40
import json
 
41
import logging
40
42
import xmlrpclib
41
43
 
 
44
from nova.openstack.common.gettextutils import _
42
45
from nova.openstack.common import timeutils
43
46
 
44
 
 
45
 
def to_primitive(value, convert_instances=False, level=0):
 
47
LOG = logging.getLogger(__name__)
 
48
 
 
49
 
 
50
def to_primitive(value, convert_instances=False, convert_datetime=True,
 
51
                 level=0, max_depth=3):
46
52
    """Convert a complex object into primitives.
47
53
 
48
54
    Handy for JSON serialization. We can optionally handle instances,
78
84
    if getattr(value, '__module__', None) == 'mox':
79
85
        return 'mock'
80
86
 
81
 
    if level > 3:
 
87
    if level > max_depth:
 
88
        LOG.error(_('Max serialization depth exceeded on object: %d %s'),
 
89
                  level, value)
82
90
        return '?'
83
91
 
84
92
    # The try block may not be necessary after the class check above,
85
93
    # but just in case ...
86
94
    try:
 
95
        recursive = functools.partial(to_primitive,
 
96
                                      convert_instances=convert_instances,
 
97
                                      convert_datetime=convert_datetime,
 
98
                                      level=level,
 
99
                                      max_depth=max_depth)
87
100
        # It's not clear why xmlrpclib created their own DateTime type, but
88
101
        # for our purposes, make it a datetime type which is explicitly
89
102
        # handled
91
104
            value = datetime.datetime(*tuple(value.timetuple())[:6])
92
105
 
93
106
        if isinstance(value, (list, tuple)):
94
 
            o = []
95
 
            for v in value:
96
 
                o.append(to_primitive(v, convert_instances=convert_instances,
97
 
                                      level=level))
98
 
            return o
 
107
            return [recursive(v) for v in value]
99
108
        elif isinstance(value, dict):
100
 
            o = {}
101
 
            for k, v in value.iteritems():
102
 
                o[k] = to_primitive(v, convert_instances=convert_instances,
103
 
                                    level=level)
104
 
            return o
105
 
        elif isinstance(value, datetime.datetime):
 
109
            return dict((k, recursive(v)) for k, v in value.iteritems())
 
110
        elif convert_datetime and isinstance(value, datetime.datetime):
106
111
            return timeutils.strtime(value)
107
112
        elif hasattr(value, 'iteritems'):
108
 
            return to_primitive(dict(value.iteritems()),
109
 
                                convert_instances=convert_instances,
110
 
                                level=level + 1)
 
113
            return recursive(dict(value.iteritems()), level=level + 1)
111
114
        elif hasattr(value, '__iter__'):
112
 
            return to_primitive(list(value),
113
 
                                convert_instances=convert_instances,
114
 
                                level=level)
 
115
            return recursive(list(value))
115
116
        elif convert_instances and hasattr(value, '__dict__'):
116
117
            # Likely an instance of something. Watch for cycles.
117
118
            # Ignore class member vars.
118
 
            return to_primitive(value.__dict__,
119
 
                                convert_instances=convert_instances,
120
 
                                level=level + 1)
 
119
            return recursive(value.__dict__, level=level + 1)
121
120
        else:
122
121
            return value
123
 
    except TypeError, e:
 
122
    except TypeError:
124
123
        # Class objects are tricky since they may define something like
125
124
        # __iter__ defined but it isn't callable as list().
126
125
        return unicode(value)