Only cache callables in the base manager

The base manager had an issue where if a property was accessed through the
__getattr__ it would be cached.

Closes-Bug: 1620722
Change-Id: Iad7ca87a30fd5fa9f8bc88a0c7f74acca2ae1a56
This commit is contained in:
David Stanek 2016-09-01 21:28:06 +00:00 committed by Lance Bragstad
parent 9a87dd509c
commit 83e3c00809
2 changed files with 42 additions and 1 deletions

View File

@ -185,6 +185,9 @@ class Manager(object):
def __getattr__(self, name):
"""Forward calls to the underlying driver."""
f = getattr(self.driver, name)
if callable(f):
# NOTE(dstanek): only if this is callable (class or function)
# cache this
setattr(self, name, f)
return f

View File

@ -38,3 +38,41 @@ class TestCreateLegacyDriver(unit.BaseTestCase):
self.assertEqual('N', mock_reporter.call_args[0][2]['remove_in'][0])
self.assertIsInstance(impl, catalog.CatalogDriverV8)
class Manager(manager.Manager):
def __init__(self, driver):
# NOTE(dstanek): I am not calling the parent's __init__ on
# purpose. I don't want to trigger the dynamic loading of a
# driver, I want to provide my own.
self.driver = driver
def test_property_passthru(self):
"""Manager delegating property call to a driver through __getattr__."""
class Driver(object):
def __init__(self):
self.counter = 0
@property
def p(self):
self.counter += 1
return self.counter
mgr = self.Manager(Driver())
# each property call should return a new value
self.assertNotEqual(mgr.p, mgr.p)
def test_callable_passthru(self):
class Driver(object):
class Inner(object):
pass
def method(self):
pass
drv = Driver()
mgr = self.Manager(drv)
self.assertEqual(drv.Inner, mgr.Inner)
self.assertEqual(drv.method, mgr.method)