[openstack-dev] [oslo][nova]Accessing nullable, not set versioned object field
Balázs Gibizer
balazs.gibizer at ericsson.com
Fri Dec 16 12:42:14 UTC 2016
Hi,
What is the expected behavior of accessing a nullable and
not set versioned object field?
See the following example code:
from oslo_versionedobjects import base
from oslo_versionedobjects import fields
@base.VersionedObjectRegistry.register
class MyObject(base.VersionedObject):
VERSION = '1.0'
fields = {
'nullable_string': fields.StringField(nullable=True),
}
my_obj = MyObject()
my_obj.nullable_string
#EOF
My naïve expectation would be that the value of my_obj.nullable_string
is None but the actual behavior is an exception:
Traceback (most recent call last):
File "ovo_nullable_test.py", line 15, in <module>
my_obj.nullable_string
File ".tox/functional/local/lib/python2.7/site-packages/oslo_versionedobjects/base.py", line 67, in getter
self.obj_load_attr(name)
File ".tox/functional/local/lib/python2.7/site-packages/oslo_versionedobjects/base.py", line 603, in obj_load_attr
_("Cannot load '%s' in the base class") % attrname)
NotImplementedError: Cannot load 'nullable_string' in the base class
Is this the correct behavior?
Then what is the expected behavior if the field is also defaulted to None?
fields = {
'nullable_string': fields.StringField(nullable=True, default=None),
}
The actual behavior is still the same exception above. Is it the correct behavior?
More real life example:
Nova has a Service object that has an availability_zone nullable field [1].
When a Service object is loaded from the db the code allows not to fill
the availability_zone field [2]. This result in a Service object instance that
will produce the above exception if the code tries to access the availability_zone
field later.
The whole problem arises when we try to send a service status notification and we
want to copy the fields from the Service object blindly to the notification payload.
To avoid the above exception we added a check to the notification payload generation
[3] to see if the given field is set or not. But this causes that if a field is lazy-loaded
but not loaded yet then we simply handle that the same way as non lazy-loaded
not set field. In the lazy-load case we might want to trigger a lazy-load during the copy but
in the non lazy-load case accessing the field would cause an exception.
Currently I don't see a way to distinguish between the two cases without triggering the
lazy-load / exception itself.
Cheers,
gibi
[1] https://github.com/openstack/nova/blob/master/nova/objects/service.py#L133
[2] https://github.com/openstack/nova/blob/master/nova/objects/service.py#L197
[3] https://github.com/openstack/nova/blob/master/nova/notifications/objects/base.py#L97
More information about the OpenStack-dev
mailing list