BIND 10 master, updated. da3b0d4f364d069ffdb47723545798ac589fae42 [master] Merge branch 'trac3373'
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Mar 11 12:14:28 UTC 2014
The branch, master has been updated
via da3b0d4f364d069ffdb47723545798ac589fae42 (commit)
via ff46195513aff7b46efdd3c4d06bd777bc86c352 (commit)
via 688e0b46933ffe567833f0e5c208117acf98c55e (commit)
via bf76c3bd4855432b96d05b67774c8d53702fe275 (commit)
from e670f65bbe881e7df6fbf3eab10da05ef48554c5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit da3b0d4f364d069ffdb47723545798ac589fae42
Merge: e670f65 ff46195
Author: Thomas Markwalder <tmark at isc.org>
Date: Tue Mar 11 08:10:01 2014 -0400
[master] Merge branch 'trac3373'
Python data.merge function now does "deep" merges
-----------------------------------------------------------------------
Summary of changes:
src/lib/python/isc/cc/data.py | 20 ++++++++++++----
src/lib/python/isc/cc/tests/data_test.py | 37 ++++++++++++++++++------------
2 files changed, 37 insertions(+), 20 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/cc/data.py b/src/lib/python/isc/cc/data.py
index 3411411..83e15be 100644
--- a/src/lib/python/isc/cc/data.py
+++ b/src/lib/python/isc/cc/data.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010-2014 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -51,14 +51,24 @@ def remove_identical(a, b):
del(a[id])
def merge(orig, new):
- """Merges the contents of new into orig, think recursive update()
- orig and new must both be dicts. If an element value is None in
- new it will be removed in orig."""
+ """Merges the contents of one dictionary into another.
+ The merge is done element by element, in order to recursivley merge
+ any elements which are themselves dictionaries. If an element value
+ is None in new it will be removed in orig. Previously this method
+ relied on dict.update but this does not do deep merges properly.
+ Raises a DataTypeError if either argument is not a dict"""
if type(orig) != dict or type(new) != dict:
raise DataTypeError("Not a dict in merge()")
- orig.update(new)
+
+ for key in new.keys():
+ if ((key in orig) and (type(orig[key]) == dict)):
+ merge(orig[key], new[key])
+ else:
+ orig[key] = new[key]
+
remove_null_items(orig)
+
def remove_null_items(d):
"""Recursively removes all (key,value) pairs from d where the
value is None"""
diff --git a/src/lib/python/isc/cc/tests/data_test.py b/src/lib/python/isc/cc/tests/data_test.py
index b8dc222..4047784 100644
--- a/src/lib/python/isc/cc/tests/data_test.py
+++ b/src/lib/python/isc/cc/tests/data_test.py
@@ -34,37 +34,37 @@ class TestData(unittest.TestCase):
c = {}
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": 1, "b": [ 1, 2 ] }
b = {}
c = { "a": 1, "b": [ 1, 2 ] }
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": 1, "b": [ 1, 2 ] }
b = { "a": 1, "b": [ 1, 2 ] }
c = {}
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": 1, "b": [ 1, 2 ] }
b = { "a": 1, "b": [ 1, 3 ] }
c = { "b": [ 1, 2 ] }
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": { "b": "c" } }
b = {}
c = { "a": { "b": "c" } }
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": { "b": "c" } }
b = { "a": { "b": "c" } }
c = {}
data.remove_identical(a, b)
self.assertEqual(a, c)
-
+
a = { "a": { "b": "c" } }
b = { "a": { "b": "d" } }
c = { "a": { "b": "c" } }
@@ -75,7 +75,7 @@ class TestData(unittest.TestCase):
a, 1)
self.assertRaises(data.DataTypeError, data.remove_identical,
1, b)
-
+
def test_merge(self):
d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
d2 = { 'a': None, 'c': { 'd': None, 'e': 3, 'f': [ 1 ] } }
@@ -87,6 +87,13 @@ class TestData(unittest.TestCase):
self.assertRaises(data.DataTypeError, data.merge, 1, d2)
self.assertRaises(data.DataTypeError, data.merge, None, None)
+ # An example that failed when merge was relying on dict.update.
+ tnew = {'d2': {'port': 54000}}
+ torig = {'ifaces': ['p8p1'], 'db': {'type': 'memfile'}, 'd2': {'ip': '127.0.0.1', 'enable': True}}
+ tchk = {'ifaces': ['p8p1'], 'db': {'type': 'memfile'}, 'd2': {'ip': '127.0.0.1', 'enable': True, 'port': 54000}}
+ tmrg = torig
+ data.merge(tmrg, tnew)
+ self.assertEqual(tmrg, tchk)
def test_split_identifier_list_indices(self):
id, indices = data.split_identifier_list_indices('a')
@@ -103,15 +110,15 @@ class TestData(unittest.TestCase):
id, indices = data.split_identifier_list_indices('a/b/c')
self.assertEqual(id, 'a/b/c')
self.assertEqual(indices, None)
-
+
id, indices = data.split_identifier_list_indices('a/b/c[1]')
self.assertEqual(id, 'a/b/c')
self.assertEqual(indices, [1])
-
+
id, indices = data.split_identifier_list_indices('a/b/c[1][2][3]')
self.assertEqual(id, 'a/b/c')
self.assertEqual(indices, [1, 2, 3])
-
+
id, indices = data.split_identifier_list_indices('a[0]/b[1]/c[2]')
self.assertEqual(id, 'a[0]/b[1]/c')
self.assertEqual(indices, [2])
@@ -124,7 +131,7 @@ class TestData(unittest.TestCase):
self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 'a[0]a[1]')
self.assertRaises(data.DataTypeError, data.split_identifier_list_indices, 1)
-
+
def test_find(self):
d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2, 'more': { 'data': 'here' } } }
@@ -151,7 +158,7 @@ class TestData(unittest.TestCase):
d3 = { 'a': [ { 'b': [ {}, { 'c': 'd' } ] } ] }
self.assertEqual(data.find(d3, 'a[0]/b[1]/c'), 'd')
self.assertRaises(data.DataNotFoundError, data.find, d3, 'a[1]/b[1]/c')
-
+
def test_set(self):
d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
d12 = { 'b': 1, 'c': { 'e': 3, 'f': [ 1 ] } }
@@ -170,7 +177,7 @@ class TestData(unittest.TestCase):
self.assertEqual(d1, d14)
data.set(d1, 'c/f[0]/g[1]', 3)
self.assertEqual(d1, d15)
-
+
self.assertRaises(data.DataTypeError, data.set, d1, 1, 2)
self.assertRaises(data.DataTypeError, data.set, 1, "", 2)
self.assertRaises(data.DataTypeError, data.set, d1, 'c[1]', 2)
@@ -205,7 +212,7 @@ class TestData(unittest.TestCase):
self.assertEqual(d3, { 'a': [ [ 1, 3 ] ] })
data.unset(d3, 'a[0][1]')
self.assertEqual(d3, { 'a': [ [ 1 ] ] })
-
+
def test_find_no_exc(self):
d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2, 'more': { 'data': 'here' } } }
self.assertEqual(data.find_no_exc(d1, ''), d1)
@@ -220,7 +227,7 @@ class TestData(unittest.TestCase):
self.assertEqual(data.find_no_exc(None, 1), None)
self.assertEqual(data.find_no_exc("123", ""), "123")
self.assertEqual(data.find_no_exc("123", ""), "123")
-
+
def test_parse_value_str(self):
self.assertEqual(data.parse_value_str("1"), 1)
self.assertEqual(data.parse_value_str("true"), True)
More information about the bind10-changes
mailing list