Don't lose AttributeError in API Wrappers
Instead of (implicitly) catching the AttributeError, and later creating and raising a new one, we just re-raise the original exception. This way all the information from the original is retained, including the name of the actual object on which it happened. Change-Id: Idc0c5a8ed5dfca6a8724e393c220baf9960564ed Closes-bug: #1274097
This commit is contained in:
parent
f96c049cda
commit
20b414db2f
@ -73,21 +73,19 @@ class APIResourceWrapper(object):
|
||||
api object as the only argument to the constructor
|
||||
"""
|
||||
_attrs = []
|
||||
_apiresource = None # Make sure _apiresource is there even in __init__.
|
||||
|
||||
def __init__(self, apiresource):
|
||||
self._apiresource = apiresource
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self._attrs:
|
||||
def __getattribute__(self, attr):
|
||||
try:
|
||||
return object.__getattribute__(self, attr)
|
||||
except AttributeError:
|
||||
if attr not in self._attrs:
|
||||
raise
|
||||
# __getattr__ won't find properties
|
||||
return self._apiresource.__getattribute__(attr)
|
||||
else:
|
||||
msg = ('Attempted to access unknown attribute "%s" on '
|
||||
'APIResource object of type "%s" wrapping resource of '
|
||||
'type "%s".') % (attr, self.__class__,
|
||||
self._apiresource.__class__)
|
||||
LOG.debug(exceptions.error_color(msg))
|
||||
raise AttributeError(attr)
|
||||
return getattr(self._apiresource, attr)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (self.__class__.__name__,
|
||||
@ -106,28 +104,30 @@ class APIDictWrapper(object):
|
||||
Attribute access is the preferred method of access, to be
|
||||
consistent with api resource objects from novaclient.
|
||||
"""
|
||||
|
||||
_apidict = {} # Make sure _apidict is there even in __init__.
|
||||
|
||||
def __init__(self, apidict):
|
||||
self._apidict = apidict
|
||||
|
||||
def __getattr__(self, attr):
|
||||
def __getattribute__(self, attr):
|
||||
try:
|
||||
return object.__getattribute__(self, attr)
|
||||
except AttributeError:
|
||||
if attr not in self._apidict:
|
||||
raise
|
||||
return self._apidict[attr]
|
||||
except KeyError:
|
||||
msg = 'Unknown attribute "%(attr)s" on APIResource object ' \
|
||||
'of type "%(cls)s"' % {'attr': attr, 'cls': self.__class__}
|
||||
LOG.debug(exceptions.error_color(msg))
|
||||
raise AttributeError(msg)
|
||||
|
||||
def __getitem__(self, item):
|
||||
try:
|
||||
return self.__getattr__(item)
|
||||
return getattr(self, item)
|
||||
except AttributeError as e:
|
||||
# caller is expecting a KeyError
|
||||
raise KeyError(e)
|
||||
|
||||
def get(self, item, default=None):
|
||||
try:
|
||||
return self.__getattr__(item)
|
||||
return getattr(self, item)
|
||||
except AttributeError:
|
||||
return default
|
||||
|
||||
|
@ -122,7 +122,7 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
|
||||
ret = api.network.tenant_floating_ip_list(self.request)
|
||||
for r, e in zip(ret, fips):
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
|
||||
self.assertEqual(r.__getattr__(attr), e.__getattr__(attr))
|
||||
self.assertEqual(getattr(r, attr), getattr(e, attr))
|
||||
self.assertEqual(r.port_id, e.instance_id)
|
||||
|
||||
def test_floating_ip_get(self):
|
||||
@ -134,7 +134,7 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
|
||||
|
||||
ret = api.network.tenant_floating_ip_get(self.request, fip.id)
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), fip.__getattr__(attr))
|
||||
self.assertEqual(getattr(ret, attr), getattr(fip, attr))
|
||||
self.assertEqual(ret.port_id, fip.instance_id)
|
||||
|
||||
def test_floating_ip_allocate(self):
|
||||
@ -147,7 +147,7 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
|
||||
|
||||
ret = api.network.tenant_floating_ip_allocate(self.request, pool_name)
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), fip.__getattr__(attr))
|
||||
self.assertEqual(getattr(ret, attr), getattr(fip, attr))
|
||||
self.assertEqual(ret.port_id, fip.instance_id)
|
||||
|
||||
def test_floating_ip_release(self):
|
||||
@ -410,7 +410,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
|
||||
rets = api.network.floating_ip_pools_list(self.request)
|
||||
for attr in ['id', 'name']:
|
||||
self.assertEqual([p.__getattr__(attr) for p in rets],
|
||||
self.assertEqual([getattr(p, attr) for p in rets],
|
||||
[p[attr] for p in ext_nets])
|
||||
|
||||
def test_floating_ip_list(self):
|
||||
@ -427,7 +427,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
self.assertEqual(len(fips), len(rets))
|
||||
for ret, exp in zip(rets, fips):
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), exp[attr])
|
||||
self.assertEqual(getattr(ret, attr), exp[attr])
|
||||
if exp['port_id']:
|
||||
dev_id = assoc_port['device_id'] if exp['port_id'] else None
|
||||
self.assertEqual(ret.instance_id, dev_id)
|
||||
@ -442,7 +442,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
|
||||
ret = api.network.tenant_floating_ip_get(self.request, fip['id'])
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), fip[attr])
|
||||
self.assertEqual(getattr(ret, attr), fip[attr])
|
||||
self.assertEqual(ret.instance_id, assoc_port['device_id'])
|
||||
|
||||
def test_floating_ip_get_unassociated(self):
|
||||
@ -452,7 +452,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
|
||||
ret = api.network.tenant_floating_ip_get(self.request, fip['id'])
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), fip[attr])
|
||||
self.assertEqual(getattr(ret, attr), fip[attr])
|
||||
self.assertIsNone(ret.instance_id)
|
||||
|
||||
def test_floating_ip_allocate(self):
|
||||
@ -468,7 +468,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
ret = api.network.tenant_floating_ip_allocate(self.request,
|
||||
ext_net['id'])
|
||||
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
|
||||
self.assertEqual(ret.__getattr__(attr), fip[attr])
|
||||
self.assertEqual(getattr(ret, attr), fip[attr])
|
||||
self.assertIsNone(ret.instance_id)
|
||||
|
||||
def test_floating_ip_release(self):
|
||||
|
Loading…
Reference in New Issue
Block a user