Fix asymmetric view of object fields
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
This commit is contained in:
@@ -341,20 +341,23 @@ class NovaObject(object):
|
||||
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)
|
||||
@@ -390,7 +393,7 @@ class NovaObject(object):
|
||||
|
||||
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):
|
||||
|
||||
@@ -599,6 +599,18 @@ class _TestObject(object):
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user