diff --git a/SoftLayer/utils.py b/SoftLayer/utils.py index cc6d7bd4f..83bd79eae 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,23 @@ def to_dict(self): for key, val in self.items()} +def dict_merge(dct1, dct2): + """Recursively merges dct2 and dct1, ideal for merging objectFilter together. + + :param dct1: A dictionary + :param dct2: A dictionary + :return: dct1 + dct2 + """ + + dct = dct1.copy() + 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: + dct[k] = dct2[k] + return dct + + 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..59bd76d86 100644 --- a/tests/basic_tests.py +++ b/tests/basic_tests.py @@ -79,6 +79,15 @@ 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"]}]}}} + result = SoftLayer.utils.dict_merge(filter1, filter2) + + self.assertEqual(result['virtualGuests']['id']['operation'], 'orderBy') + self.assertNotIn('id', filter1['virtualGuests']) + self.assertEqual(result['virtualGuests']['hostname']['operation'], 'etst') + class TestNestedDict(testing.TestCase):