From 4867c2d18d5faf29747fd989bce0b445a3b0ff71 Mon Sep 17 00:00:00 2001 From: Sam Betts Date: Wed, 20 Jan 2016 10:40:11 +0000 Subject: [PATCH] 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 --- oslo_versionedobjects/base.py | 8 ++-- oslo_versionedobjects/tests/test_objects.py | 41 +++++++++++++++------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/oslo_versionedobjects/base.py b/oslo_versionedobjects/base.py index 8aa5dc4..71fc92f 100644 --- a/oslo_versionedobjects/base.py +++ b/oslo_versionedobjects/base.py @@ -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 diff --git a/oslo_versionedobjects/tests/test_objects.py b/oslo_versionedobjects/tests/test_objects.py index 705780d..94202bb 100755 --- a/oslo_versionedobjects/tests/test_objects.py +++ b/oslo_versionedobjects/tests/test_objects.py @@ -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):