From 605201f93bdde7eeebc063691f46d00822205899 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Tue, 5 Apr 2016 10:31:23 -0400 Subject: [PATCH] Properly handle overridden Body properties The Resource._get_mapping method was previously overwriting mapping entries as it traversed the MRO, so while it would properly map name=nombre on the first pass through the class it's trying to find, it would then look at base classes, including the base Resource, and then overwrite that mapping to go back to name=name. This was just seen as an issue while applying the refactoring to AvailabilityZone in compute, where the name=zoneName mapping wasn't properly working. This change fixes that. Change-Id: I21f343fdbf3c6d5696e3f074d56d96b4fe4faaba --- openstack/resource2.py | 5 ++++- openstack/tests/unit/test_resource2.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/openstack/resource2.py b/openstack/resource2.py index e0dfa26b..94c231df 100644 --- a/openstack/resource2.py +++ b/openstack/resource2.py @@ -332,7 +332,10 @@ class Resource(object): for klass in cls.__mro__: for key, value in klass.__dict__.items(): if isinstance(value, component): - mapping[key] = value.name + # Make sure base classes don't end up overwriting + # mappings we've found previously in subclasses. + if key not in mapping: + mapping[key] = value.name return mapping @classmethod diff --git a/openstack/tests/unit/test_resource2.py b/openstack/tests/unit/test_resource2.py index 58439ce5..878b881e 100644 --- a/openstack/tests/unit/test_resource2.py +++ b/openstack/tests/unit/test_resource2.py @@ -509,6 +509,21 @@ class TestResource(base.TestCase): self.assertIn("name", resource2.Resource._body_mapping()) self.assertIn("id", resource2.Resource._body_mapping()) + def test__mapping_overrides(self): + # Iterating through the MRO used to wipe out overrides of mappings + # found in base classes. + new_name = "MyName" + new_id = "MyID" + + class Test(resource2.Resource): + name = resource2.Body(new_name) + id = resource2.Body(new_id) + + mapping = Test._body_mapping() + + self.assertEqual(new_name, mapping["name"]) + self.assertEqual(new_id, mapping["id"]) + def test__body_mapping(self): class Test(resource2.Resource): x = resource2.Body("x")