From 20b414db2fcb3863ad37e3e3fc88d264acdc9f32 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Wed, 29 Jan 2014 14:06:46 +0100 Subject: [PATCH] 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 --- openstack_dashboard/api/base.py | 36 +++++++++---------- .../test/api_tests/network_tests.py | 16 ++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/openstack_dashboard/api/base.py b/openstack_dashboard/api/base.py index 5a9cb3f4a6..e1d034815a 100644 --- a/openstack_dashboard/api/base.py +++ b/openstack_dashboard/api/base.py @@ -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 diff --git a/openstack_dashboard/test/api_tests/network_tests.py b/openstack_dashboard/test/api_tests/network_tests.py index e4830c3047..7f7bfd5ec4 100644 --- a/openstack_dashboard/test/api_tests/network_tests.py +++ b/openstack_dashboard/test/api_tests/network_tests.py @@ -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):