# HG changeset patch # User Sverre Rabbelier # Date 1232640197 0 # Node ID 0b416bb14970877e84dc2d8c18733ef12d1a6ab3 # Parent 91a43d0aa29ad37a2de35d4f9eddc7f850d48c2e Extend dicts.merge to be (optionally) recursive This is very useful when dealing for views that expect to be inhereted from but wish to provide default values. Patch by: Sverre Rabbelier diff -r 91a43d0aa29a -r 0b416bb14970 app/soc/logic/dicts.py --- a/app/soc/logic/dicts.py Thu Jan 22 16:01:51 2009 +0000 +++ b/app/soc/logic/dicts.py Thu Jan 22 16:03:17 2009 +0000 @@ -43,12 +43,14 @@ return result -def merge(target, updates): +def merge(target, updates, sub_merge=False, recursive=False): """Like the builtin 'update' method but does not overwrite existing values. Args: target: The dictionary that is to be updated, may be None updates: A dictionary containing new values for the original dict + sub_merge: Merge a dict or list present in both target and update + recursive: Determines whether merge_subdicts is recursive Returns: the target dict, with any missing values from updates merged in, in-place. @@ -60,6 +62,19 @@ for key, value in updates.iteritems(): if key not in target: target[key] = value + elif sub_merge: + target_value = target[key] + + # try to merge dicts + if isinstance(value, dict) and isinstance(target_value, dict): + # the merge becomes recursive by specifying it not only as value + # to sub_merge but also to recursive + target[key] = merge(target_value, value, + sub_merge=recursive, recursive=recursive) + + # try to merge lists + if isinstance(value, list) and isinstance(target_value, list): + target[key] = target_value + value return target