From 3ae09aebff156c165e346304476804aa1f3b4172 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 13 May 2015 16:06:52 +0200 Subject: [PATCH] Enhance dict compat of VersionedObjectDictCompat Add more dictionary methods to VersionedObjectDictCompat: * __iter__() * keys(), iterkeys() * values(), itervalues() Thanks to new methods, dict constructor now accepts VersionedObjectDictCompat: it's possible to write directly dict(obj) instead of having to write dict(obj.iteritems()). On Python 3, items() now returns an iterator instead of a list, to respect Python 3 dictionary API, as the new keys() and values() methods. Keep iterkeys(), itervalues() and iteritems() on Python 3, even if Python 3 dictionaries don't have these methods, just to ease the transition from Python 2 to Python 3 in Nova. Change-Id: I4c52d44c7ba49f98b1bbd123209fce7b70ade98d --- oslo_versionedobjects/base.py | 31 +++++++++++++++++++-- oslo_versionedobjects/tests/test_objects.py | 24 ++++++++++++---- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/oslo_versionedobjects/base.py b/oslo_versionedobjects/base.py index 79b5521..c14e10b 100644 --- a/oslo_versionedobjects/base.py +++ b/oslo_versionedobjects/base.py @@ -645,13 +645,38 @@ class VersionedObjectDictCompat(object): attribute access. """ - def iteritems(self): + def __iter__(self): for name in self.obj_fields: if (self.obj_attr_is_set(name) or name in self.obj_extra_fields): - yield name, getattr(self, name) + yield name - items = lambda self: list(self.iteritems()) + iterkeys = __iter__ + + def itervalues(self): + for name in self: + yield getattr(self, name) + + def iteritems(self): + for name in self: + yield name, getattr(self, name) + + if six.PY3: + # NOTE(haypo): Python 3 dictionaries don't have iterkeys(), + # itervalues() or iteritems() methods. These methods are provided to + # ease the transition from Python 2 to Python 3. + keys = iterkeys + values = itervalues + items = iteritems + else: + def keys(self): + return list(self.iterkeys()) + + def values(self): + return list(self.itervalues()) + + def items(self): + return list(self.iteritems()) def __getitem__(self, name): return getattr(self, name) diff --git a/oslo_versionedobjects/tests/test_objects.py b/oslo_versionedobjects/tests/test_objects.py index 2ca2e48..45b7eb9 100755 --- a/oslo_versionedobjects/tests/test_objects.py +++ b/oslo_versionedobjects/tests/test_objects.py @@ -645,12 +645,26 @@ class _TestObject(object): self.assertRaises(ValueError, fail) def test_object_dict_syntax(self): - obj = MyObj(foo=123, bar='bar') + obj = MyObj(foo=123, bar=u'text') self.assertEqual(obj['foo'], 123) - self.assertEqual(sorted(obj.items(), key=lambda x: x[0]), - [('bar', 'bar'), ('foo', 123)]) - self.assertEqual(sorted(list(obj.iteritems()), key=lambda x: x[0]), - [('bar', 'bar'), ('foo', 123)]) + self.assertIn('bar', obj) + self.assertNotIn('missing', obj) + self.assertEqual(sorted(iter(obj)), + ['bar', 'foo']) + self.assertEqual(sorted(obj.keys()), + ['bar', 'foo']) + self.assertEqual(sorted(obj.iterkeys()), + ['bar', 'foo']) + self.assertEqual(sorted(obj.values(), key=str), + [123, u'text']) + self.assertEqual(sorted(obj.itervalues(), key=str), + [123, u'text']) + self.assertEqual(sorted(obj.items()), + [('bar', u'text'), ('foo', 123)]) + self.assertEqual(sorted(list(obj.iteritems())), + [('bar', u'text'), ('foo', 123)]) + self.assertEqual(dict(obj), + {'foo': 123, 'bar': u'text'}) def test_load(self): obj = MyObj()