From de6aa5833a6832be1deb9cb104ca0ba56d0e36e7 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 9 Sep 2015 11:06:12 -0700 Subject: [PATCH] Fix object field type calling conventions This removes the _Callable hack in ironic.objects.fields, and fixes all the remaining cases where old-style fields were used. This change has been complete in nova for probably two years now, and is a necessary thing to cleanup before progressing further with oslo.versionedobjects conversions. Change-Id: I43c45ce4d3ce4de04e43b68f24435600aaefb74f Related-Bug: #1461239 --- ironic/objects/base.py | 7 +++--- ironic/objects/fields.py | 31 ++++++++------------------ ironic/tests/objects/test_conductor.py | 8 +++++-- ironic/tests/objects/test_objects.py | 10 +++++---- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/ironic/objects/base.py b/ironic/objects/base.py index 1053c3c998..cdb9dfb7ae 100644 --- a/ironic/objects/base.py +++ b/ironic/objects/base.py @@ -51,7 +51,7 @@ def make_class_properties(cls): for name, field in supercls.fields.items(): if name not in cls.fields: cls.fields[name] = field - for name, typefn in cls.fields.items(): + for name, field in cls.fields.items(): def getter(self, name=name): attrname = get_attrname(name) @@ -59,10 +59,11 @@ def make_class_properties(cls): self.obj_load_attr(name) return getattr(self, attrname) - def setter(self, value, name=name, typefn=typefn): + def setter(self, value, name=name, field=field): self._changed_fields.add(name) try: - return setattr(self, get_attrname(name), typefn(value)) + field_value = field.coerce(self, name, value) + return setattr(self, get_attrname(name), field_value) except Exception: attr = "%s.%s" % (self.obj_name(), name) LOG.exception(_LE('Error setting %(attr)s'), diff --git a/ironic/objects/fields.py b/ironic/objects/fields.py index 3b22f26742..5c2565dc2d 100644 --- a/ironic/objects/fields.py +++ b/ironic/objects/fields.py @@ -21,44 +21,31 @@ from oslo_versionedobjects import fields as object_fields from ironic.common import utils -class _Callable(object): - """Helper class to make this work like old-style fields. - - This class makes the object able to be called like a function, - which emulates the old interface that objects are expecting. This - should be removed once objects/base.py is updated to stop using the - old interface for the fields. - - """ - def __call__(self, value): - return self.coerce(None, None, value) - - -class IntegerField(object_fields.IntegerField, _Callable): +class IntegerField(object_fields.IntegerField): pass -class UUIDField(object_fields.UUIDField, _Callable): +class UUIDField(object_fields.UUIDField): pass -class StringField(object_fields.StringField, _Callable): +class StringField(object_fields.StringField): pass -class DateTimeField(object_fields.DateTimeField, _Callable): +class DateTimeField(object_fields.DateTimeField): pass -class BooleanField(object_fields.BooleanField, _Callable): +class BooleanField(object_fields.BooleanField): pass -class ListOfStringsField(object_fields.ListOfStringsField, _Callable): +class ListOfStringsField(object_fields.ListOfStringsField): pass -class FlexibleDict(object_fields.FieldType, _Callable): +class FlexibleDict(object_fields.FieldType): @staticmethod def coerce(obj, attr, value): if isinstance(value, six.string_types): @@ -66,7 +53,7 @@ class FlexibleDict(object_fields.FieldType, _Callable): return dict(value) -class FlexibleDictField(object_fields.AutoTypedField, _Callable): +class FlexibleDictField(object_fields.AutoTypedField): AUTO_TYPE = FlexibleDict() # TODO(lucasagomes): In our code we've always translated None to {}, @@ -84,5 +71,5 @@ class MACAddress(object_fields.FieldType): return utils.validate_and_normalize_mac(value) -class MACAddressField(object_fields.AutoTypedField, _Callable): +class MACAddressField(object_fields.AutoTypedField): AUTO_TYPE = MACAddress() diff --git a/ironic/tests/objects/test_conductor.py b/ironic/tests/objects/test_conductor.py index 7ea8c617de..caea164819 100644 --- a/ironic/tests/objects/test_conductor.py +++ b/ironic/tests/objects/test_conductor.py @@ -76,8 +76,12 @@ class TestConductorObject(base.DbTestCase): c = objects.Conductor.get_by_hostname(self.context, host) # ensure timestamps have tzinfo datetime_field = fields.DateTimeField() - self.assertEqual(datetime_field(t0), c.updated_at) + self.assertEqual( + datetime_field.coerce(datetime_field, 'updated_at', t0), + c.updated_at) c.refresh() - self.assertEqual(datetime_field(t1), c.updated_at) + self.assertEqual( + datetime_field.coerce(datetime_field, 'updated_at', t1), + c.updated_at) self.assertEqual(expected, mock_get_cdr.call_args_list) self.assertEqual(self.context, c._context) diff --git a/ironic/tests/objects/test_objects.py b/ironic/tests/objects/test_objects.py index e36f3ae6a9..887d7e32ad 100644 --- a/ironic/tests/objects/test_objects.py +++ b/ironic/tests/objects/test_objects.py @@ -23,6 +23,7 @@ import six from ironic.common import exception from ironic.objects import base +from ironic.objects import fields from ironic.objects import utils from ironic.tests import base as test_base @@ -32,9 +33,9 @@ gettext.install('ironic') class MyObj(base.IronicObject): VERSION = '1.5' - fields = {'foo': int, - 'bar': str, - 'missing': str, + fields = {'foo': fields.IntegerField(), + 'bar': fields.StringField(), + 'missing': fields.StringField(), } def obj_load_attr(self, attrname): @@ -428,7 +429,8 @@ class _TestObject(object): def test_refresh_object(self): class TestObj(base.IronicObject): - fields = {'foo': int, 'bar': str} + fields = {'foo': fields.IntegerField(), + 'bar': fields.StringField()} obj = TestObj(self.context) current_obj = TestObj(self.context)