[openstack-dev] [oslo][nova]Accessing nullable, not set versioned object field

Balázs Gibizer balazs.gibizer at ericsson.com
Tue Dec 20 19:09:25 UTC 2016

From: Dan Smith <dms at danplanet.com>
Sent: 16 December 2016 16:33
>> NotImplementedError: Cannot load 'nullable_string' in the base class
>> Is this the correct behavior?
> Yes, that's the expected behaviour.


>> 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?
> Yes. So, what the default=None does is describe the behaviour of the
> field when obj_set_defaults() is called. It does *not* describe what is
> returned if the field *value* is accessed before being populated.
> What you're looking for is the obj_attr_is_set() method:
> if MyObject.obj_attr_is_set('nullable_string'):
>     print my_obj.nullable_string

I think you meant s/MyObject/my_obj/ above. However, in modern times,
it's better to use:

 if 'nullable_string' in myobj

On a per-object basis, it may also be reasonable to define
obj_load_attr() to provide the default for a field if it's not set and
attempted to be loaded.

> In addition to the obj_attr_is_set() method, use the obj_set_defaults()
> method to manually set all fields that have a default=XXX value to XXX
> if those fields have not yet been manually set:

There's another wrinkle here. The default=XXX stuff was actually
introduced before we had obj_set_defaults(), and for a very different
reason. That reason was confusing and obscure, and mostly supportive of
the act of converting nova from dicts to objects. If you look in fields,
there is an obscure handling of default, where if you _set_ a field to
None that has a default and is not nullable, it will gain the default value.

It's confusing and I wish we had never done it, but.. it's part of the
contract now and I'd have to do a lot of digging to see if we can remove
it (probably can from Nova, but...).

Your use above is similar to this, so I just wanted to point it out in
case you came across it and it led you to thinking your original example
would work.


Thank you for the answers. Following up on this. Is it considered a good
practice to instantiate an ovo but keeping some non-lazy loaded
fields unset?

I think the user of the ovo instance should be able to assume that the
fields declared in the ovo are accessible after the ovo is instantiated
without manually checking obj_attr_is_set().

I know that lazy-loaded fields are a special case because the user of 
the ovo instance will see that the lazy-loaded field is not set if calls 
obj_attr_is_set() but as soon as user code tries to access it the 
backend will fetch and return the value of the field.

However there are cases in nova where an instantiated ovo has some
not set, not lazy-loaded field. For example Service.availability_zone  is
not lazy-loaded [2] but it is allowed to be not set by [1].
Is it considered a bug? Should the code [1] set Serivce.availability_zone to 
None instead of keeping it not set?


[1] https://github.com/openstack/nova/blob/master/nova/objects/service.py#L197
[2] https://github.com/openstack/nova/blob/master/nova/objects/service.py#L221

OpenStack Development Mailing List (not for usage questions)
Unsubscribe: OpenStack-dev-request at lists.openstack.org?subject:unsubscribe

openstack-dev mailing list
This list for the developers of OpenStack to discuss development issues and roadmap. It is focused on the next release of OpenStack: you should post on this list if ...


More information about the OpenStack-dev mailing list