blob: cf06c9b433cee167c5c98e06d64cc7a2e68faff3 [file] [log] [blame]
def iteritems(d):
"""Create a key-value iterator for the given dict in both Python 2.x and
Python 3.x environments"""
if hasattr(d, "iteritems"):
return d.iteritems()
return d.items()
def merge_dictionaries(first, second):
"""Given two dictionaries, create a third that defines all specified
key/value pairs. This merge_dictionaries is performed "deeply" on any nested
dictionaries. If a value is defined for the same key by both dictionaries,
an exception will be raised."""
result = dict(first)
for key, value in iteritems(second):
if key in result and result[key] != value:
if isinstance(result[key], dict) and isinstance(value, dict):
result[key] = merge_dictionaries(result[key], value)
elif result[key] != value:
raise TypeError("merge_dictionaries: refusing to overwrite " +
"attribute: `%s`" % key)
else:
result[key] = value
return result
if __name__ == "__main__":
assert merge_dictionaries({}, {}) == {}
assert merge_dictionaries({}, {"a": 23}) == {"a": 23}
assert merge_dictionaries({"a": 23}, {"b": 45}) == {"a": 23, "b": 45}
e = None
try:
merge_dictionaries({"a": 23}, {"a": 45})
except Exception as _e:
e = _e
assert isinstance(e, TypeError)
assert merge_dictionaries({"a": 23}, {"a": 23}) == {"a": 23}
assert merge_dictionaries({"a": {"b": 23}}, {"a": {"c": 45}}) == {"a": {"b": 23, "c": 45}}
assert merge_dictionaries({"a": {"b": 23}}, {"a": {"b": 23}}) == {"a": {"b": 23}}
e = None
try:
merge_dictionaries({"a": {"b": 23}}, {"a": {"b": 45}})
except Exception as _e:
e = _e
assert isinstance(e, TypeError)