[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


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

class MyObject(base.VersionedObject):

    VERSION = '1.0'
    fields = {
        'nullable_string': fields.StringField(nullable=True),

my_obj = MyObject()


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>
  File ".tox/functional/local/lib/python2.7/site-packages/oslo_versionedobjects/base.py", line 67, in getter
  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.


[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