Skip to content

Commit

Permalink
Fix asymmetric view of object fields
Browse files Browse the repository at this point in the history
This adds an obj_fields property which returns a combined view of the
real field key names as well as the extra_fields. This will help
avoid bugs where we forget to consider extra_fields.

Change-Id: I93351ccc9f87817deca06e9a2d94f82a3dd5f51a
Closes-bug: 1223888
  • Loading branch information
kk7ds committed Sep 11, 2013
1 parent be57317 commit 4e842e3
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
11 changes: 7 additions & 4 deletions nova/objects/base.py
Expand Up @@ -341,20 +341,23 @@ def obj_attr_is_set(self, attrname):
False if not. Raises AttributeError if attrname is not
a valid attribute for this object.
"""
if (attrname not in self.fields and
attrname not in self.obj_extra_fields):
if attrname not in self.obj_fields:
raise AttributeError(
_("%(objname)s object has no attribute '%(attrname)s'") %
{'objname': self.obj_name(), 'attrname': attrname})
return hasattr(self, get_attrname(attrname))

@property
def obj_fields(self):
return self.fields.keys() + self.obj_extra_fields

# dictish syntactic sugar
def iteritems(self):
"""For backwards-compatibility with dict-based objects.
NOTE(danms): May be removed in the future.
"""
for name in self.fields.keys() + self.obj_extra_fields:
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)
Expand Down Expand Up @@ -390,7 +393,7 @@ def get(self, key, value=NotSpecifiedSentinel):
NOTE(danms): May be removed in the future.
"""
if key not in self.fields:
if key not in self.obj_fields:
raise AttributeError("'%s' object has no attribute '%s'" % (
self.__class__, key))
if value != NotSpecifiedSentinel and not self.obj_attr_is_set(key):
Expand Down
12 changes: 12 additions & 0 deletions nova/tests/objects/test_objects.py
Expand Up @@ -599,6 +599,18 @@ def test_get_changes(self):
obj.obj_reset_changes()
self.assertEqual({}, obj.obj_get_changes())

def test_obj_fields(self):
class TestObj(base.NovaObject):
fields = {'foo': int}
obj_extra_fields = ['bar']

@property
def bar(self):
return 'this is bar'

obj = TestObj()
self.assertEqual(['foo', 'bar'], obj.obj_fields)


class TestObject(_LocalTest, _TestObject):
pass
Expand Down

0 comments on commit 4e842e3

Please sign in to comment.