From 53fc65625e25aa4206aa0712ce2811448836557c Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Tue, 13 Apr 2021 16:39:38 -0500 Subject: [PATCH 1/3] Added a utility to merge objectFilters, #1459 1461 --- SoftLayer/utils.py | 16 ++++++++++++++++ tests/basic_tests.py | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/SoftLayer/utils.py b/SoftLayer/utils.py index cc6d7bd4f..bd7f33c91 100644 --- a/SoftLayer/utils.py +++ b/SoftLayer/utils.py @@ -5,6 +5,7 @@ :license: MIT, see LICENSE for more details. """ +import collections import datetime import re import time @@ -57,6 +58,21 @@ def to_dict(self): for key, val in self.items()} +def dict_merge(dct1, dct2): + """Recursively merges dct2 into dct1, ideal for merging objectFilter together. + + :param dct1: dict onto which the merge is executed + :param dct2: dct merged into dct + :return: None + """ + + for k, v in dct2.items(): + if (k in dct1 and isinstance(dct1[k], dict) and isinstance(dct2[k], collections.Mapping)): + dict_merge(dct1[k], dct2[k]) + else: + dct1[k] = dct2[k] + + def query_filter(query): """Translate a query-style string to a 'filter'. diff --git a/tests/basic_tests.py b/tests/basic_tests.py index b430a3d5e..f4dbe6085 100644 --- a/tests/basic_tests.py +++ b/tests/basic_tests.py @@ -79,6 +79,16 @@ def test_timezone(self): self.assertEqual(datetime.timedelta(0), time.dst()) self.assertEqual(datetime.timedelta(0), time.utcoffset()) + def test_dict_merge(self): + filter1 = {"virtualGuests":{"hostname":{"operation":"etst"}}} + filter2 = {"virtualGuests":{"id":{"operation":"orderBy","options":[{"name":"sort","value":["DESC"]}]}}} + SoftLayer.utils.dict_merge(filter1, filter2) + + self.assertEqual(filter1['virtualGuests']['id']['operation'], 'orderBy') + self.assertEqual(filter1['virtualGuests']['hostname']['operation'], 'etst') + + + class TestNestedDict(testing.TestCase): From ffce9b3020437e99d46d850165c2d5a713dd7ad0 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Tue, 13 Apr 2021 16:48:06 -0500 Subject: [PATCH 2/3] changed dict_merge to return a merged dictionary --- SoftLayer/utils.py | 14 ++++++++------ tests/basic_tests.py | 7 ++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/SoftLayer/utils.py b/SoftLayer/utils.py index bd7f33c91..c0851ec4a 100644 --- a/SoftLayer/utils.py +++ b/SoftLayer/utils.py @@ -59,18 +59,20 @@ def to_dict(self): def dict_merge(dct1, dct2): - """Recursively merges dct2 into dct1, ideal for merging objectFilter together. + """Recursively merges dct2 and dct1, ideal for merging objectFilter together. - :param dct1: dict onto which the merge is executed - :param dct2: dct merged into dct - :return: None + :param dct1: A dictionary + :param dct2: A dictionary + :return: dct1 + dct2 """ + dct = dct1.copy() for k, v in dct2.items(): if (k in dct1 and isinstance(dct1[k], dict) and isinstance(dct2[k], collections.Mapping)): - dict_merge(dct1[k], dct2[k]) + dct[k] = dict_merge(dct1[k], dct2[k]) else: - dct1[k] = dct2[k] + dct[k] = dct2[k] + return dct def query_filter(query): diff --git a/tests/basic_tests.py b/tests/basic_tests.py index f4dbe6085..dbbcbef0a 100644 --- a/tests/basic_tests.py +++ b/tests/basic_tests.py @@ -82,10 +82,11 @@ def test_timezone(self): def test_dict_merge(self): filter1 = {"virtualGuests":{"hostname":{"operation":"etst"}}} filter2 = {"virtualGuests":{"id":{"operation":"orderBy","options":[{"name":"sort","value":["DESC"]}]}}} - SoftLayer.utils.dict_merge(filter1, filter2) + result = SoftLayer.utils.dict_merge(filter1, filter2) - self.assertEqual(filter1['virtualGuests']['id']['operation'], 'orderBy') - self.assertEqual(filter1['virtualGuests']['hostname']['operation'], 'etst') + self.assertEqual(result['virtualGuests']['id']['operation'], 'orderBy') + self.assertNotIn('id', filter1['virtualGuests']) + self.assertEqual(result['virtualGuests']['hostname']['operation'], 'etst') From 554cbbd33fbc3c40c2751c8f2182e92c5d24a3ff Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Tue, 13 Apr 2021 18:42:37 -0500 Subject: [PATCH 3/3] tox fixes --- SoftLayer/utils.py | 2 +- tests/basic_tests.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/SoftLayer/utils.py b/SoftLayer/utils.py index c0851ec4a..83bd79eae 100644 --- a/SoftLayer/utils.py +++ b/SoftLayer/utils.py @@ -67,7 +67,7 @@ def dict_merge(dct1, dct2): """ dct = dct1.copy() - for k, v in dct2.items(): + for k, _ in dct2.items(): if (k in dct1 and isinstance(dct1[k], dict) and isinstance(dct2[k], collections.Mapping)): dct[k] = dict_merge(dct1[k], dct2[k]) else: diff --git a/tests/basic_tests.py b/tests/basic_tests.py index dbbcbef0a..59bd76d86 100644 --- a/tests/basic_tests.py +++ b/tests/basic_tests.py @@ -80,8 +80,8 @@ def test_timezone(self): self.assertEqual(datetime.timedelta(0), time.utcoffset()) def test_dict_merge(self): - filter1 = {"virtualGuests":{"hostname":{"operation":"etst"}}} - filter2 = {"virtualGuests":{"id":{"operation":"orderBy","options":[{"name":"sort","value":["DESC"]}]}}} + filter1 = {"virtualGuests": {"hostname": {"operation": "etst"}}} + filter2 = {"virtualGuests": {"id": {"operation": "orderBy", "options": [{"name": "sort", "value": ["DESC"]}]}}} result = SoftLayer.utils.dict_merge(filter1, filter2) self.assertEqual(result['virtualGuests']['id']['operation'], 'orderBy') @@ -89,8 +89,6 @@ def test_dict_merge(self): self.assertEqual(result['virtualGuests']['hostname']['operation'], 'etst') - - class TestNestedDict(testing.TestCase): def test_basic(self):