[lxc-devel] [pylxd/master] Fix Operation class to allow unknown attributes

ajkavanagh on Github lxc-bot at linuxcontainers.org
Thu Mar 8 15:49:21 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 628 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180308/779fc198/attachment.bin>
-------------- next part --------------
From 48fe55b83a3cdd9add2fad380ae9d687ea17b5c4 Mon Sep 17 00:00:00 2001
From: Alex Kavanagh <alex at ajkavanagh.co.uk>
Date: Thu, 8 Mar 2018 16:46:12 +0100
Subject: [PATCH] Fix Operation class to allow unknown attributes

lxd 3.0.0-beta{x} grew a new feature in that the operation metadata
includes a 'description' tag.  This breaks pylxd, and so this fix adds
the 'description' key, and also then makes the class more robust to
handle unknown attributes in the future.  Note that ALL the other
classes got this fix in 2.2.4.

Fixes bug: #284
---
 pylxd/models/operation.py            | 18 +++++++++++++++---
 pylxd/tests/models/test_operation.py | 16 ++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/pylxd/models/operation.py b/pylxd/models/operation.py
index 1594680..94e102d 100644
--- a/pylxd/models/operation.py
+++ b/pylxd/models/operation.py
@@ -11,6 +11,9 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+
+import warnings
+
 from pylxd import exceptions
 
 
@@ -19,8 +22,8 @@ class Operation(object):
 
     __slots__ = [
         '_client',
-        'class', 'created_at', 'err', 'id', 'may_cancel', 'metadata',
-        'resources', 'status', 'status_code', 'updated_at']
+        'class', 'created_at', 'description', 'err', 'id', 'may_cancel',
+        'metadata', 'resources', 'status', 'status_code', 'updated_at']
 
     @classmethod
     def wait_for_operation(cls, client, operation_id):
@@ -40,7 +43,16 @@ def get(cls, client, operation_id):
     def __init__(self, **kwargs):
         super(Operation, self).__init__()
         for key, value in kwargs.items():
-            setattr(self, key, value)
+            try:
+                setattr(self, key, value)
+            except AttributeError:
+                # ignore attributes we don't know about -- prevent breakage
+                # in the future if new attributes are added.
+                warnings.warn(
+                    'Attempted to set unknown attribute "{}" '
+                    'on instance of "{}"'
+                    .format(key, self.__class__.__name__))
+                pass
 
     def wait(self):
         """Wait for the operation to complete and return."""
diff --git a/pylxd/tests/models/test_operation.py b/pylxd/tests/models/test_operation.py
index 8c74cc9..d42b83e 100644
--- a/pylxd/tests/models/test_operation.py
+++ b/pylxd/tests/models/test_operation.py
@@ -12,6 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import json
+
 from pylxd import exceptions, models
 from pylxd.tests import testing
 
@@ -56,3 +58,17 @@ def error(request, context):
         an_operation = models.Operation.get(self.client, name)
 
         self.assertRaises(exceptions.LXDAPIException, an_operation.wait)
+
+    def test_unknown_attribute(self):
+        self.add_rule({
+            'text': json.dumps({
+                'type': 'sync',
+                'metadata': {'id': 'operation-unknown',
+                             'metadata': {'return': 0},
+                             'unknown': False},
+                }),
+            'method': 'GET',
+            'url': r'^http://pylxd.test/1.0/operations/operation-unknown$',
+        })
+        url = '/1.0/operations/operation-unknown'
+        models.Operation.get(self.client, url)


More information about the lxc-devel mailing list