adapters: fix compat for auto accessors

The keystone interface rebase to the Endpoint base class re-uses
the auto_accessors approach from RelationBase which makes the
interface smell a little different to other Endpoint based interfaces.

Check and map any keys listed in auto_accessors for all relation
class types rather than just for RelationBase.

This also fixes a minor issue where self.accessors was reset to []
when the auto_accessors attribute was not found in the relation
overwriting any accessors passed in during object construction.

Change-Id: I4481c6d8ad5c9f0a8bc5e892d1d7472be83f3454
This commit is contained in:
James Page 2022-09-21 11:02:44 +01:00
parent 581300632b
commit bf2e867e9e
3 changed files with 41 additions and 17 deletions

View File

@ -187,23 +187,22 @@ class OpenStackRelationAdapter(object):
(lambda name: property(
lambda self: getattr(
self.relation, name)))(name))
else:
try:
self.accessors.extend(self.relation.auto_accessors)
except AttributeError:
self.accessors = []
for field in self.accessors:
meth_name = field.replace('-', '_')
# Get the relation property dynamically
# Note the additional lambda name: is to create a closure over
# meth_name so that a new 'name' gets created for each loop,
# otherwise the same variable meth_name is referenced in each
# of the internal lambdas. i.e. this is (lambda x: ...)(value)
setattr(self.__class__,
meth_name,
(lambda name: property(
lambda self: getattr(
self.relation, name)()))(meth_name))
try:
self.accessors.extend(self.relation.auto_accessors)
except AttributeError:
pass
for field in self.accessors:
meth_name = field.replace('-', '_')
# Get the relation property dynamically
# Note the additional lambda name: is to create a closure over
# meth_name so that a new 'name' gets created for each loop,
# otherwise the same variable meth_name is referenced in each
# of the internal lambdas. i.e. this is (lambda x: ...)(value)
setattr(self.__class__,
meth_name,
(lambda name: property(
lambda self: getattr(
self.relation, name)()))(meth_name))
class MemcacheRelationAdapter(OpenStackRelationAdapter):

View File

@ -30,6 +30,10 @@ deps = -r{toxinidir}/test-requirements.txt
basepython = python3.8
deps = -r{toxinidir}/test-requirements.txt
[testenv:py310]
basepython = python3.10
deps = -r{toxinidir}/test-requirements.txt
[testenv:pep8]
basepython = python3
deps = -r{toxinidir}/test-requirements.txt

View File

@ -136,6 +136,16 @@ class MyEndpointRelation(reactive.Endpoint):
return self.value
class MyEndpointAutoAccessorsRelation(
MyEndpointRelation,
metaclass=reactive.relations.AutoAccessors):
auto_accessors = ['foo', 'bar']
def get_remote(self, key):
return key
class TestOpenStackRelationAdapter(unittest.TestCase):
def test_class(self):
@ -184,6 +194,17 @@ class TestOpenStackRelationAdapter(unittest.TestCase):
with self.assertRaises(AttributeError):
self.assertFalse(ad.a_function)
def test_class_with_endpoint_auto_accessors_relation(self):
er = MyEndpointAutoAccessorsRelation('my-name')
ad = adapters.OpenStackRelationAdapter(er)
self.assertEqual(ad.a_property, 'has value in config rendering')
er.value = 'can change after instantiation'
self.assertEqual(ad.a_property, 'can change after instantiation')
with self.assertRaises(AttributeError):
self.assertFalse(ad.a_function)
self.assertEqual(ad.foo, 'foo')
self.assertEqual(ad.bar, 'bar')
class FakeMemcacheRelation():