Also check for the existence of `items` in to_primitive()

Change-Id: If4636566a642ddf2e6e13cc014abca4ad68d1977
This commit is contained in:
Sirushti Murugesan 2015-09-25 12:28:26 +05:30
parent c9f0304b94
commit 96886ce299
2 changed files with 49 additions and 0 deletions

View File

@ -153,6 +153,9 @@ def to_primitive(value, convert_instances=False, convert_datetime=True,
for k, v in six.iteritems(value))
elif hasattr(value, 'iteritems'):
return recursive(dict(value.iteritems()), level=level + 1)
# Python 3 does not have iteritems
elif hasattr(value, 'items'):
return recursive(dict(value.items()), level=level + 1)
elif hasattr(value, '__iter__'):
return list(map(recursive, value))
elif convert_instances and hasattr(value, '__dict__'):

View File

@ -198,6 +198,52 @@ class ToPrimitiveTestCase(test_base.BaseTestCase):
# an exception due to excessive recursion depth.
jsonutils.to_primitive(x)
def test_items(self):
# Use items() when iteritems() is not available.
class ItemsClass(object):
def __init__(self):
self.data = dict(a=1, b=2, c=3)
def items(self):
return self.data.items()
x = ItemsClass()
p = jsonutils.to_primitive(x)
self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
def test_precedence_items_iteritems(self):
class ItemsIterItemsClass(object):
def items(self):
return {'items': 'items'}
def iteritems(self):
return {'iteritems': 'iteritems'}
x = ItemsIterItemsClass()
p = jsonutils.to_primitive(x)
# Prefer iteritems over items
self.assertEqual(p, {'iteritems': 'iteritems'})
def test_mapping(self):
# Make sure collections.Mapping is converted to a dict
# and not a list.
class MappingClass(collections.Mapping):
def __init__(self):
self.data = dict(a=1, b=2, c=3)
def __getitem__(self, val):
return self.data[val]
def __iter__(self):
return iter(self.data)
def __len__(self):
return len(self.data)
x = MappingClass()
p = jsonutils.to_primitive(x)
self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
def test_instance(self):
class MysteryClass(object):
a = 10