From f58e7ee5dcfb1b7d853f3a3deb6a44ae22d0690b Mon Sep 17 00:00:00 2001 From: Zach Moody Date: Mon, 10 Feb 2020 18:01:12 -0600 Subject: [PATCH] Fixes #221 - Account for changes in choices field NetBox 2.7 changes the structure of the objects returned in choice fields temporarily until v2.8 is released. This PR causes these fields to serialize to `value` when both `id` and `value` fields are present. --- pynetbox/core/response.py | 7 +++++-- tests/unit/test_response.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/pynetbox/core/response.py b/pynetbox/core/response.py index 57fac7c4..63e528c2 100644 --- a/pynetbox/core/response.py +++ b/pynetbox/core/response.py @@ -25,8 +25,7 @@ def get_return(lookup, return_fields=None): """Returns simple representations for items passed to lookup. Used to return a "simple" representation of objects and collections - sent to it via lookup. If lookup is an IPNetwork object immediately - return the string representation. Otherwise, we look to see if + sent to it via lookup. Otherwise, we look to see if lookup is a "choices" field (dict with only 'id' and 'value') or a nested_return. Finally, we check if it's a Record, if so simply return a string. Order is important due to nested_return @@ -41,6 +40,10 @@ def get_return(lookup, return_fields=None): return lookup[i] else: if hasattr(lookup, i): + # check if this is a "choices" field record + # from a NetBox 2.7 server. + if sorted(dict(lookup)) == sorted(["id", "value", "label"]): + return getattr(lookup, "value") return getattr(lookup, i) if isinstance(lookup, Record): diff --git a/tests/unit/test_response.py b/tests/unit/test_response.py index eea9c5db..c9581a53 100644 --- a/tests/unit/test_response.py +++ b/tests/unit/test_response.py @@ -112,6 +112,43 @@ def test_dict(self): test = Record(test_values, None, None) self.assertEqual(dict(test), test_values) + def test_choices_idempotence_prev27(self): + test_values = { + "id": 123, + "choices_test": { + "value": 1, + "label": "test", + }, + } + test = Record(test_values, None, None) + test.choices_test = 1 + self.assertFalse(test._diff()) + + def test_choices_idempotence_v27(self): + test_values = { + "id": 123, + "choices_test": { + "value": "test", + "label": "test", + "id": 1, + }, + } + test = Record(test_values, None, None) + test.choices_test = "test" + self.assertFalse(test._diff()) + + def test_choices_idempotence_v28(self): + test_values = { + "id": 123, + "choices_test": { + "value": "test", + "label": "test", + }, + } + test = Record(test_values, None, None) + test.choices_test = "test" + self.assertFalse(test._diff()) + def test_hash(self): endpoint = Mock() endpoint.name = "test-endpoint"