Make sure functions in child object registries work

This patch ensures that the VersionedObjectRegistry.__new__ function
always returns the correct class thats being created so that overridden
functions are applied correctly, when using a subclassed object
registry. Without this patch when using multiple child object registries
only the first child's overridden functions work correctly.

Change-Id: I11fef67b5bd16377086027d72f8e417c2221b5b4
Closes-Bug: #1536113
This commit is contained in:
Sam Betts 2016-01-20 10:40:11 +00:00
parent 6e801d1c03
commit 4867c2d18d
2 changed files with 35 additions and 14 deletions
oslo_versionedobjects

@ -101,11 +101,13 @@ class VersionedObjectRegistry(object):
def __new__(cls, *args, **kwargs):
if not VersionedObjectRegistry._registry:
VersionedObjectRegistry._registry = \
object.__new__(cls, *args, **kwargs)
VersionedObjectRegistry._registry = object.__new__(
VersionedObjectRegistry, *args, **kwargs)
VersionedObjectRegistry._registry._obj_classes = \
collections.defaultdict(list)
return VersionedObjectRegistry._registry
self = object.__new__(cls, *args, **kwargs)
self._obj_classes = VersionedObjectRegistry._registry._obj_classes
return self
def registration_hook(self, cls, index):
pass

@ -289,21 +289,40 @@ class TestRegistry(test.TestCase):
mock_hook.assert_called_once_with(TestObjectNewer, 0)
def test_subclassability(self):
class MyRegistry(base.VersionedObjectRegistry):
pass
class MyRegistryOne(base.VersionedObjectRegistry):
@MyRegistry.register
class ObjectInSubclassedRegistry(object):
fields = {}
def registration_hook(self, cls, index):
cls.reg_to = "one"
@classmethod
def obj_name(cls):
return cls.__name__
class MyRegistryTwo(base.VersionedObjectRegistry):
self.assertIn('ObjectInSubclassedRegistry',
MyRegistry.obj_classes())
self.assertIn('ObjectInSubclassedRegistry',
def registration_hook(self, cls, index):
cls.reg_to = "two"
@MyRegistryOne.register
class AVersionedObject1(base.VersionedObject):
VERSION = '1.0'
fields = {'baz': fields.Field(fields.Integer())}
@MyRegistryTwo.register
class AVersionedObject2(base.VersionedObject):
VERSION = '1.0'
fields = {'baz': fields.Field(fields.Integer())}
self.assertIn('AVersionedObject1',
MyRegistryOne.obj_classes())
self.assertIn('AVersionedObject2',
MyRegistryOne.obj_classes())
self.assertIn('AVersionedObject1',
MyRegistryTwo.obj_classes())
self.assertIn('AVersionedObject2',
MyRegistryTwo.obj_classes())
self.assertIn('AVersionedObject1',
base.VersionedObjectRegistry.obj_classes())
self.assertIn('AVersionedObject2',
base.VersionedObjectRegistry.obj_classes())
self.assertEqual(AVersionedObject1.reg_to, "one")
self.assertEqual(AVersionedObject2.reg_to, "two")
class TestObjMakeList(test.TestCase):