factorize deep_diff function in salt.utils.dictdiffer module

This commit is contained in:
Bruno Binet 2016-12-15 11:20:08 +01:00
parent a4a59cce14
commit 4596b71657
4 changed files with 43 additions and 108 deletions

View File

@ -37,10 +37,9 @@ Basic auth setup
- is_default: true
'''
from __future__ import absolute_import
from copy import deepcopy
from collections import Mapping
from salt.ext.six import string_types
from salt.utils.dictdiffer import deep_diff
def __virtual__():
@ -153,7 +152,7 @@ def present(name,
__salt__['grafana4.update_datasource'](
datasource['id'], profile=profile, **data)
ret['result'] = True
ret['changes'] = _deep_diff(datasource, data, ignore=['id', 'orgId'])
ret['changes'] = deep_diff(datasource, data, ignore=['id', 'orgId'])
ret['comment'] = 'Data source {0} updated'.format(name)
return ret
@ -195,35 +194,3 @@ def _get_json_data(defaults=None, **kwargs):
if v is None:
kwargs[k] = defaults.get(k)
return kwargs
def _deep_diff(old, new, ignore=[]):
res = {}
old = deepcopy(old)
new = deepcopy(new)
stack = [(old, new, False)]
while len(stack) > 0:
tmps = []
tmp_old, tmp_new, reentrant = stack.pop()
for key in set(tmp_old.keys() + tmp_new.keys()):
if key in tmp_old and key in tmp_new \
and tmp_old[key] == tmp_new[key]:
del tmp_old[key]
del tmp_new[key]
continue
if not reentrant:
if key in tmp_old and key in ignore:
del tmp_old[key]
if key in tmp_new and key in ignore:
del tmp_new[key]
if isinstance(tmp_old.get(key), Mapping) \
and isinstance(tmp_new.get(key), Mapping):
tmps.append((tmp_old[key], tmp_new[key], False))
if tmps:
stack.extend([(tmp_old, tmp_new, True)] + tmps)
if old:
res['old'] = old
if new:
res['new'] = new
return res

View File

@ -39,11 +39,10 @@ Basic auth setup
- country: ""
'''
from __future__ import absolute_import
from collections import Mapping
from copy import deepcopy
from salt.ext.six import string_types
from salt.utils import dictupdate
from salt.utils.dictdiffer import deep_diff
from requests.exceptions import HTTPError
@ -112,7 +111,7 @@ def present(name,
if create:
dictupdate.update(ret['changes']['address'], data)
else:
dictupdate.update(ret['changes'], _deep_diff(org['address'], data))
dictupdate.update(ret['changes'], deep_diff(org['address'], data))
prefs = __salt__['grafana4.get_org_prefs'](name, profile=profile)
data = _get_json_data(theme=theme, homeDashboardId=home_dashboard_id,
@ -122,7 +121,7 @@ def present(name,
if create:
dictupdate.update(ret['changes'], data)
else:
dictupdate.update(ret['changes'], _deep_diff(prefs, data))
dictupdate.update(ret['changes'], deep_diff(prefs, data))
if users:
db_users = {}
@ -153,7 +152,7 @@ def present(name,
if create:
dictupdate.update(ret['changes'], new_db_users)
else:
dictupdate.update(ret['changes'], _deep_diff(db_users, new_db_users))
dictupdate.update(ret['changes'], deep_diff(db_users, new_db_users))
ret['result'] = True
if not create:
@ -200,35 +199,3 @@ def _get_json_data(defaults=None, **kwargs):
if v is None:
kwargs[k] = defaults.get(k)
return kwargs
def _deep_diff(old, new, ignore=[]):
res = {}
old = deepcopy(old)
new = deepcopy(new)
stack = [(old, new, False)]
while len(stack) > 0:
tmps = []
tmp_old, tmp_new, reentrant = stack.pop()
for key in set(tmp_old.keys() + tmp_new.keys()):
if key in tmp_old and key in tmp_new \
and tmp_old[key] == tmp_new[key]:
del tmp_old[key]
del tmp_new[key]
continue
if not reentrant:
if key in tmp_old and key in ignore:
del tmp_old[key]
if key in tmp_new and key in ignore:
del tmp_new[key]
if isinstance(tmp_old.get(key), Mapping) \
and isinstance(tmp_new.get(key), Mapping):
tmps.append((tmp_old[key], tmp_new[key], False))
if tmps:
stack.extend([(tmp_old, tmp_new, True)] + tmps)
if old:
res['old'] = old
if new:
res['new'] = new
return res

View File

@ -34,11 +34,10 @@ Basic auth setup
- is_admin: true
'''
from __future__ import absolute_import
from copy import deepcopy
from collections import Mapping
from salt.ext.six import string_types
from salt.utils import dictupdate
from salt.utils.dictdiffer import deep_diff
def __virtual__():
@ -98,13 +97,13 @@ def present(name,
defaults=user_data):
__salt__['grafana4.update_user'](user['id'], profile=profile, **data)
dictupdate.update(
ret['changes'], _deep_diff(
ret['changes'], deep_diff(
user_data, __salt__['grafana4.get_user_data'](user['id'])))
if user['isAdmin'] != is_admin:
__salt__['grafana4.update_user_permissions'](
user['id'], isGrafanaAdmin=is_admin, profile=profile)
dictupdate.update(ret['changes'], _deep_diff(
dictupdate.update(ret['changes'], deep_diff(
user, __salt__['grafana4.get_user'](name, profile)))
ret['result'] = True
@ -165,35 +164,3 @@ def _get_json_data(defaults=None, **kwargs):
if v is None:
kwargs[k] = defaults.get(k)
return kwargs
def _deep_diff(old, new, ignore=[]):
res = {}
old = deepcopy(old)
new = deepcopy(new)
stack = [(old, new, False)]
while len(stack) > 0:
tmps = []
tmp_old, tmp_new, reentrant = stack.pop()
for key in set(tmp_old.keys() + tmp_new.keys()):
if key in tmp_old and key in tmp_new \
and tmp_old[key] == tmp_new[key]:
del tmp_old[key]
del tmp_new[key]
continue
if not reentrant:
if key in tmp_old and key in ignore:
del tmp_old[key]
if key in tmp_new and key in ignore:
del tmp_new[key]
if isinstance(tmp_old.get(key), Mapping) \
and isinstance(tmp_new.get(key), Mapping):
tmps.append((tmp_old[key], tmp_new[key], False))
if tmps:
stack.extend([(tmp_old, tmp_new, True)] + tmps)
if old:
res['old'] = old
if new:
res['new'] = new
return res

View File

@ -9,6 +9,8 @@
Originally posted at http://stackoverflow.com/questions/1165352/fast-comparison-between-two-python-dictionary/1165552#1165552
Available at repository: https://github.com/hughdbrown/dictdiffer
'''
from copy import deepcopy
from collections import Mapping
def diff(current_dict, past_dict):
@ -41,3 +43,35 @@ class DictDiffer(object):
def unchanged(self):
return set(o for o in self.intersect if self.past_dict[o] == self.current_dict[o])
def deep_diff(old, new, ignore=[]):
res = {}
old = deepcopy(old)
new = deepcopy(new)
stack = [(old, new, False)]
while len(stack) > 0:
tmps = []
tmp_old, tmp_new, reentrant = stack.pop()
for key in set(tmp_old.keys() + tmp_new.keys()):
if key in tmp_old and key in tmp_new \
and tmp_old[key] == tmp_new[key]:
del tmp_old[key]
del tmp_new[key]
continue
if not reentrant:
if key in tmp_old and key in ignore:
del tmp_old[key]
if key in tmp_new and key in ignore:
del tmp_new[key]
if isinstance(tmp_old.get(key), Mapping) \
and isinstance(tmp_new.get(key), Mapping):
tmps.append((tmp_old[key], tmp_new[key], False))
if tmps:
stack.extend([(tmp_old, tmp_new, True)] + tmps)
if old:
res['old'] = old
if new:
res['new'] = new
return res