From d32bbed004b76333c3e72e6c1f97dcde88e11edd Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Fri, 13 Feb 2015 15:24:04 -0500 Subject: [PATCH] 4138: Revamp Node Manager driver proxying in BaseComputeNodeDriver. Accessing attributes through a super() proxy does not invoke __getattr__ on base classes, so the old implementation made it impossible for subclasses to be agnostic about whether a method was implemented in BaseComputeNodeDriver or the real libcloud driver. This version makes that possible. It's also a little nicer because now the class will report these method names to dir(), hasattr(), etc. --- .../arvnodeman/computenode/driver/__init__.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/services/nodemanager/arvnodeman/computenode/driver/__init__.py b/services/nodemanager/arvnodeman/computenode/driver/__init__.py index c06bba347d..369bb8f953 100644 --- a/services/nodemanager/arvnodeman/computenode/driver/__init__.py +++ b/services/nodemanager/arvnodeman/computenode/driver/__init__.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, print_function import libcloud.common.types as cloud_types +from libcloud.compute.base import NodeDriver from ...config import NETWORK_ERRORS @@ -35,14 +36,6 @@ class BaseComputeNodeDriver(object): def _init_ping_host(self, ping_host): self.ping_host = ping_host - def __getattr__(self, name): - # Proxy non-extension methods to the real driver. - if (not name.startswith('_') and not name.startswith('ex_') - and hasattr(self.real, name)): - return getattr(self.real, name) - else: - return super(BaseComputeNodeDriver, self).__getattr__(name) - def search_for(self, term, list_method, key=lambda item: item.id): cache_key = (list_method, term) if cache_key not in self.SEARCH_CACHE: @@ -96,3 +89,16 @@ class BaseComputeNodeDriver(object): # exactly an Exception, or a better-known higher-level exception. return (isinstance(exception, cls.CLOUD_ERRORS) or getattr(exception, '__class__', None) is Exception) + + # Now that we've defined all our own methods, delegate generic, public + # attributes of libcloud drivers that we haven't defined ourselves. + def _delegate_to_real(attr_name): + return property( + lambda self: getattr(self.real, attr_name), + lambda self, value: setattr(self.real, attr_name, value), + doc=getattr(getattr(NodeDriver, attr_name), '__doc__', None)) + + _locals = locals() + for _attr_name in dir(NodeDriver): + if (not _attr_name.startswith('_')) and (_attr_name not in _locals): + _locals[_attr_name] = _delegate_to_real(_attr_name) -- 2.30.2